Skip to content

Changelog

All notable changes to EasySpeak are documented here. This file is the canonical, GitHub-independent record of releases. It is updated once per release. The format loosely follows Keep a Changelog, and the project adheres to Semantic Versioning.

0.13.0 · Welcome, KDE Plasma! · 2026-10-11

EasySpeak Comes to KDE Plasma, Says What Went Wrong, and Licenses Every File the REUSE Way

EasySpeak now runs on KDE Plasma too. Its tray icon puts it to sleep, wakes it up, opens Help and About, and switches "Start at Login" on or off. "Open settings", "open calculator" and other app names open the KDE counterparts, and the About information appears in Plasma's own look where kdialog is installed. A new Compatibility page shows which features work on which desktop; the mouse grid, head tracking and typing dictated text still need GNOME. The packages no longer pull GNOME's libraries onto other desktops, and every file's copyright and license is declared following the REUSE specification.

When something goes wrong, EasySpeak now says so out loud instead of only in the terminal, and Ctrl+C ends it quietly. It also understands more ways of asking: "dictation", "deactivate yourself", "exit the application", "open trash", "close downloads", and opening or closing the About dialog by name.

What's Changed

  • Settings raises the open preferences dialog by @bittner in #201
  • "Stop listening" releases the mic at once by @bittner in #200
  • Dictation Plugin: compare Title Classes with lowercase, remove unneccessary "inserted 0 chars" when triggered by has_focused_text_field() by @SolanumForte in #202
  • Remove the Bencher integration by @bittner in #205
  • Tray icon for KDE Plasma and other desktops by @bittner in #204
  • REUSE-compliant licensing by @bittner in #206
  • About dialog by voice, more natural replies by @bittner in #208
  • Dictation fails gracefully on KDE Plasma by @bittner in #209
  • Open System Settings on KDE Plasma by @bittner in #210
  • Open KDE apps on KDE Plasma by @bittner in #212
  • About dialog works on NixOS by @bittner in #211
  • No GNOME libraries forced on other desktops by @bittner in #218
  • Mouse grid says why it can't appear by @bittner in #214
  • Core reports failures out loud by @bittner in #217
  • More ways to ask for the About dialog by @bittner in #219
  • Browser plugin reports failures out loud by @bittner in #215
  • Fix test failing on Python 3.10–3.12 by @bittner in #222
  • Ctrl+C quits without a stack trace by @bittner in #220
  • More ways to ask EasySpeak to quit by @bittner in #221
  • Head tracking says why it stopped by @bittner in #216
  • Say "dictation" to dictate by @bittner in #224
  • Compatibility page, KDE in the desktop badge by @bittner in #223
  • Native About window on KDE Plasma by @bittner in #226
  • "Start at Login" in the KDE tray menu by @bittner in #225
  • Trash, and closing folders, by voice by @bittner in #227
  • KDE docs: Start at Login, native About by @bittner in #228
  • Close the About dialog by voice by @bittner in #229
  • Package checks for KDE support by @bittner in #230

Full Changelog: 0.12.0...0.13.0

0.12.0 · A Faster Ear · 2026-09-14

Parakeet Recognizes the Speech by Default, in Its Own Package, and Dictation Keeps Its Capitals

Speech is now recognized by NVIDIA's Parakeet TDT v3 instead of Whisper: one model for 25 European languages that tells them apart by itself, several times faster on a short command than the Whisper model of a language pack, and with punctuation and capitalization of its own. It ships as a third package, easyspeak-stt-parakeet, installed once next to the app and a language pack, and is fetched on first start where downloads are allowed. Whisper stays behind EASYSPEAK_STT=whisper and takes over, with a note at startup, when the Parakeet model is not there or the language is one it does not cover. Dictation no longer lowercases what was said: "United States" and German nouns keep their capitals, while the control words still match however they were cased.

The About window credits every model and voice EasySpeak ships with its owner and license, the plugin contract diagram matches the reference one, and the docs deploy of a release no longer trips over the deploy of the merge before it.

What's Changed

  • Serialize the docs deploys of a release by @bittner in #189
  • Retry the docs push on a fresh gh-pages when another deploy won by @bittner in #190
  • Show the translator and vocabulary in the plugin contract diagram by @bittner in #191
  • Mark the translator and vocabulary optional in the plugin contract by @bittner in #192
  • Dash the plugin boxes in the contract diagram like the reference one by @bittner in #193
  • Describe the translator and vocabulary as independent by @bittner in #194
  • Keep the capitalization Whisper writes when dictating by @bittner in #195
  • Credit the speech models and voices in the About window by @bittner in #197
  • Recognize speech with Parakeet TDT v3 by default by @bittner in #196
  • Package the Parakeet speech model as easyspeak-stt-parakeet by @bittner in #198

Full Changelog: 0.11.0...0.12.0

0.11.0 · Commands in Your Language · 2026-09-13

Commands, Dictation Control Words and the Help Screen in the User's Language, and a Microphone That Stays Open

With EASYSPEAK_LANGUAGE set, or the new --language option, the general, app, folder, media, sleep and system commands take that language's words — "öffne den Rechner", "lauter", "geh schlafen" — and so do the words inside dictation, "Komma", "neue Zeile", "Notizen beenden", and the word that starts it, "Diktat"; the English words keep working everywhere. What a plugin listens for is a vocabulary.toml table beside its reply catalog, one per language, so tuning a phrase, or adding the spellings Whisper makes of it, is editing a file; the help screen lists the words of the active language, built from those tables. The grid, browser and head-tracking modes still take English words. A typo in the language code is reported at startup, and so is why replies fall back to English.

The microphone now stays open after every command, whether it replied, acted silently or did not understand, and gives up only after about ten seconds of silence, so "open documents" or a misheard word no longer sends you back to the wake word. The docs' diagrams enlarge on click, and the file manager can be closed by its everyday names — the one your desktop is configured for.

What's Changed

  • Speak the dictation control words in the user's language by @bittner in #174
  • Add a --language option to the command line by @bittner in #176
  • Report an unknown language and why replies fall back to English by @bittner in #177
  • Show the help screen in the active language by @bittner in #181
  • Start dictation with the active language's word by @bittner in #180
  • Take commands in the user's language in the simple plugins by @bittner in #182
  • Make the docs' diagrams enlarge on click and show the plugin locale by @bittner in #184
  • Keep the mic open after every command, reply or miss by @bittner in #187
  • Build the help lines from the vocabulary tables by @bittner in #185
  • Hear the file manager as Whisper writes it by @bittner in #186

Full Changelog: 0.10.0...0.11.0

0.10.0 · Answers in Your Language · 2026-09-12

Spoken Replies in German, Italian, French and Spanish, a Language Pack for Each, and Plugins as Packages

EasySpeak now answers in the language it is spoken to. EASYSPEAK_LANGUAGE=de, it, fr or es with the matching language pack gives dictation, spoken replies and the voice in that language; commands stay English words, as do the dictation control words for now. The replies are gettext catalogs beside the code that speaks them, one per plugin, with per-string fallback to English, and the voice follows the language of the replies — so a language without a translation, or without its voice pack installed, gets English replies in the English voice rather than a voice reading the wrong language. Italian, French and Spanish packs join the German one; a further language is a pins.toml entry, an nfpm file and eleven .po files, and just translations <lang> and just check-translations keep the catalogs in step with the code.

Underneath, plugins are Python packages now, each carrying its own locale/, and route by an explicit PRIORITY instead of numeric filename prefixes; a plain module still loads. EASYSPEAK_MODELS_DIR says where language packs are installed, which the Nix dev shell uses to link packs in on demand (easyspeak-lang de it) instead of fetching every language up front. As since 0.9.0, this release needs packs on the per-language layout: easyspeak-lang-en 1.1.0 or newer.

What's Changed

  • Complete the 0.9.0 changelog entry by @bittner in #160
  • Build every language pack into the Nix dev shell by @bittner in #161
  • Read the replies with the voice of their own language by @bittner in #162
  • Speak the replies in the user's language, German first by @bittner in #164
  • Add the Italian language pack and Italian replies by @bittner in #165
  • Add the French language pack and French replies by @bittner in #166
  • Add the Spanish language pack and Spanish replies by @bittner in #167
  • Tidy up before the next release by @bittner in #168
  • Answer in English when the language's voice is not installed by @bittner in #171
  • Fetch language packs on demand in the Nix dev shell by @bittner in #170
  • Check that the reply catalogs keep up with the code by @bittner in #169

Full Changelog: 0.9.0...0.10.0

0.9.0 · Speaking Your Language · 2026-09-12

Dictation in Other Languages, Per-Language Packs, and Voice Control Proven on a Real Desktop

EASYSPEAK_LANGUAGE sets the language you dictate in — commands stay English words — and picks the language pack installed for it. Each pack now lives under its own /opt/easyspeak/models/<language>, so several can sit side by side, and German is the first beyond English: easyspeak-lang-de pairs the multilingual Whisper small with the Piper thorsten voice. This release needs easyspeak-lang-en 1.1.0 or newer, as the 1.0.0 pack installs the old tree. Translating the dictation control words (comma, stop notes, …) is still ahead.

The bulk of the work between the two releases, though, is a dozen fixes from running EasySpeak on a real GNOME/Wayland desktop rather than reading the source: every mode's microphone loop now runs from the core, so the tray and the idle timeout keep working inside grid, browser and dictation modes; command words match as whole words, so "upgrade" no longer opens the grid; dictation learns backspace, scratch that and keystrokes such as enter, tab, escape and the arrows; the browser gets voice toggles for GPU rendering and ad blocking, and detects ad blocking by asking qutebrowser itself; and an opt-in require wake word keeps a video playing through the speakers from being transcribed as commands. wl-clipboard becomes a hard dependency, the Nix dev shell supplies every tool the code invokes, and line coverage is back at 100%.

What's Changed

  • docs: Update installation instructions by @bittner in #131
  • Add a CLI option to print version information by @bittner in #132
  • Fix benchmark job by allowing Whisper model downloads by @bittner in #134
  • Fix voice control breaking down in practice by @ctsdownloads in #135
  • fix(clipboard): drop the xclip fallback and require wl-clipboard by @ctsdownloads in #136
  • refactor(browser): hold session state on core, not module globals by @ctsdownloads in #137
  • fix(dictation): match command words as whole words by @ctsdownloads in #138
  • fix: whole-word grid triggers, and scroll past overflow-hidden by @ctsdownloads in #139
  • chore: strip explanatory comments by @ctsdownloads in #140
  • fix(browser): stop hint mode hearing its own prompt by @ctsdownloads in #141
  • feat(dictation): backspace and scratch that by @ctsdownloads in #142
  • fix(dictation): backspace no longer cancels scratch that by @ctsdownloads in #143
  • feat(dictation): send enter, tab, escape and arrow keys by @ctsdownloads in #144
  • feat: keystroke commands in dictation and browser mode by @ctsdownloads in #145
  • feat(browser): voice toggles for rendering and ad blocking by @ctsdownloads in #146
  • feat: option to require the wake word inside modes by @ctsdownloads in #147
  • fix: wait for the real wake word in modes, not a text prefix by @ctsdownloads in #148
  • fix(dictation): do not ask for the wake word before every sentence by @ctsdownloads in #149
  • fix(nix): supply the runtime tools the code actually invokes by @ctsdownloads in #150
  • Restore full line coverage of the voice-control paths by @bittner in #151
  • Detect ad blocking by asking qutebrowser, not a stray python3 by @bittner in #152
  • Support languages other than English by @bittner in #156
  • Adding environment variable for customizing the language of the Whisper model by @SolanumForte in #154
  • Give each language pack its own models directory by @bittner in #157
  • Add the German language pack by @bittner in #158

New Contributors

  • @SolanumForte made their first contribution in #154

Full Changelog: 0.8.0...0.9.0

0.8.0 · Voices on Their Own · 2026-07-04

Independently Versioned Language Packs and Verifiable, Pinned Model Downloads

Language packs now carry their own version and ship on their own release tag (lang-en-1.0.0 is the first), decoupled from the application's release cadence — a lang-en-* tag builds and publishes each pack on its own, and points at a Releases view filtered to that language.

Version pinning also becomes transparent: a checked-in pins.toml records exactly which model and dependency versions an install resolves to, and speech models are now verified against per-file checksums — so an offline-by-default setup stays reproducible and tamper-evident. This groundwork also paves the way for a proper NixOS package, whose fully-pinned, hash-verified builds need exactly this manifest. Rounding it out, filesystem handling moves to pathlib, prek pre-commit hooks add file-hygiene and shellcheck gates, the API reference regains its missing modules, and a flaky freedesktop link check (a WAF 418) is quieted.

What's Changed

  • Transparent version pinning (pins.toml) by @bittner in #116
  • Adopt pathlib for filesystem paths by @bittner in #118
  • Pin per-file checksums for speech models by @bittner in #119
  • Add missing modules to the API documentation by @bittner in #122
  • Give language packs their own version by @bittner in #123
  • Split language-pack builds from the application build by @bittner in #124
  • Add prek pre-commit hooks for file hygiene and shellcheck by @bittner in #125
  • Fix flaky link check on freedesktop's WAF (418) by @bittner in #127
  • Release language packs on their own trigger by @bittner in #126
  • Fold language-pack builds into the Release workflow by @bittner in #128
  • Skip the Docs workflow for language-pack tags by @bittner in #129
  • Link the language pack to its filtered Releases view by @bittner in #130

Full Changelog: 0.7.0...0.8.0

0.7.0 · Offline by Default · 2026-07-01

A Strict Offline Switch, a Clean Abort When the Model Is Missing, and --preview

A single EASYSPEAK_OFFLINE variable now governs whether EasySpeak may reach the network, and it defaults to strict — nothing is fetched at runtime unless you opt in, true to the fully-local ethos. The recognition model loads locally first, so a bundled or previously-cached model needs no network at all. When it is missing under the default, startup aborts cleanly: an actionable message (set EASYSPEAK_OFFLINE=relaxed to download it, or install a language pack) and a non-zero exit, mirroring the existing no-microphone handling. Set relaxed to opt into the on-demand base.en download from Hugging Face, announced with a warning.

A CLI-usability fix renames the one-shot --show desktop-integration option to --preview, aligning the mental model of the two paired options: --preview now prints exactly what --configure would install, so the two read as a single preview-then-apply gesture rather than an odd show/configure mismatch. It also takes exactly one item, since concatenating several files to stdout served no purpose. Under the hood the data and extension folders move back under src/, the packaging tests gain a README, and the GitHub Releases workflow is documented in CONTRIBUTING.

What's Changed

  • Gate implicit Whisper downloads behind EASYSPEAK_OFFLINE by @bittner in #114
  • Rename --show CLI option to --preview by @bittner in #113
  • Move data and extension folders back to src/ by @bittner in #111
  • Add README for the packaging tests by @bittner in #112
  • Document the GitHub Releases workflow in CONTRIBUTING by @bittner in #110

Full Changelog: 0.6.0...0.7.0

0.6.0 · Made to Configure · 2026-06-30

Configurable Chimes, a Single Hotkey Variable, and Versioned Docs

EASYSPEAK_* environment variables now drive cross-platform/distro configurability: rather than carrying platform-specific patches, EasySpeak exposes whatever differs between systems as a variable you set — and documents every one of them in the generated reference. The wake and sleep chimes, for one, stayed silent under uv run easyspeak in the Nix dev shell (they only played under nix run, which rewrote the freedesktop sound path that doesn't exist on NixOS); instead of special-casing NixOS, the sound directory now lives behind a new EASYSPEAK_SOUNDS_DIR variable. The two hotkey variables collapse into one: EASYSPEAK_HOTKEY now holds the combo itself (default ctrl+shift; set it empty or to off/none to disable), with a mistyped combo logging a warning and disabling the listener instead of silently arming a dead key.

The documentation site moves to mike's native versioning, so the version selector switches in place and always knows which version it is on. The in-development docs from main now serve at /latest/, the most recent release at /stable/, and every tagged release stays archived under its own /<version>/ path.

What's Changed

  • Make desktop sounds configurable, document env vars by @bittner in #103
  • Serve main docs at the root, redirect /latest to it by @bittner in #104
  • Tidy the docs deploy scripts and names by @bittner in #106
  • Consolidate the env-var reference in the Usage guide by @bittner in #105
  • Switch docs deploy to mike's convention by @bittner in #107
  • Merge the two HOTKEY env vars and validate the combo by @bittner in #108

Full Changelog: 0.5.0...0.6.0

0.5.0 · New Domain, Modular Extension · 2026-06-30

Quick Settings, the easyspeak.dev Domain, and a Modular Extension

EasySpeak gains a GNOME Quick Settings toggle as an alternative to the panel tray icon, and the extension's Settings dialog grows desktop-integration controls and a Website link. Under the hood the wake-word engine is swapped to pyopen-wakeword and the default Python moves to 3.14, while spawned desktop apps no longer inherit the dev shell's libraries — so the file manager and friends launch against their own.

The project also settles into its own easyspeak.dev domain everywhere, and the GNOME extension moves into a UUID folder (gnome@easyspeak.dev), splits from a monolith into compositor-only ES modules behind a thin entrypoint, and now derives its per-user autostart entry from the canonical desktop file instead of a drifting copy. Rounding it out: CI is hardened with lint, link-checking, and packaging verification; the distro-package checks are grouped behind a single build; and the extension-refresh unit no longer fails when its uv interpreter has vanished.

What's Changed

  • Swap wake-word backend to pyopen-wakeword and bump default Python to 3.14 by @bittner in #93
  • Add a Quick Settings toggle as an alternative to the tray icon by @bittner in #96
  • Add extension Settings dialog, desktop integration, and Website link by @bittner in #91
  • Stop leaking dev-shell libraries into spawned desktop apps by @bittner in #95
  • Use the newly acquired easyspeak.dev domain everywhere by @bittner in #98
  • Move GNOME extension to a UUID folder, rename to gnome@easyspeak.dev by @bittner in #100
  • Split GNOME extension into ES modules; consolidate autostart entry by @bittner in #101
  • Fix extension-refresh unit failing on a vanished uv interpreter by @bittner in #89
  • Harden CI: lint, link check, packaging verification, and release fold by @bittner in #97
  • Group the distro package checks; rename "native" → "distro" by @bittner in #102
  • Add a tray icon and menu screenshot, reduce file sizes by @bittner in #94
  • docs: Show the tray menu and Quick Settings side by side by @bittner in #99

Full Changelog: 0.4.0...0.5.0

0.4.0 · Packaged and Polished · 2026-06-24

Native Packages & a Docs Site

EasySpeak now ships as native Debian (.deb) and Fedora (.rpm) packages, with the language data split into separate packages so you install only the voices you need. Dictation now actually works — backed by a proper AT-SPI backend that reports failures honestly instead of silently doing nothing — and gains a silent, keyboard hold-to-dictate activation for when you'd rather not speak the wake word. The GNOME tray grows an About dialog and a Help entry, and the extension is renamed simply "EasySpeak".

Under the hood, terminal output moved from print() to structured logging, the codebase adopted Ruff's full "ALL" ruleset with curated exceptions, and a batch of post-0.3.0 review findings were cleaned up; EasySpeak also fails gracefully now when an audio device or gdbus is missing. Rounding it out is a hosted MkDocs and Material documentation site on GitHub Pages — complete with screenshots and Git-LFS-tracked media — while CI is streamlined onto main as the dev branch is phased out.

What's Changed

  • feat(packaging): native .deb/.rpm with split language data by @bittner in #77
  • Make dictation work: provide the AT-SPI backend and report failures honestly by @bittner in #69
  • feat(core): silent (keyboard) hold-to-dictate activation by @bittner in #70
  • feat(tray): add About dialog and Help to the tray menu by @bittner in #73
  • refactor(extension): rename "EasySpeak Grid" to "EasySpeak" by @bittner in #74
  • Switch terminal output from print() to logging by @bittner in #68
  • Adopt Ruff "ALL" ruleset with curated exceptions by @bittner in #65
  • fix: address post-0.3.0 review findings (browser-launch trap, AT-SPI caret, hotkey shutdown) by @bittner in #72
  • Fail gracefully when audio device or gdbus is missing by @bittner in #86
  • docs: hosted MkDocs + Material + mkdocstrings site on GitHub Pages by @bittner in #71
  • Integrate screenshots in documentation by @bittner in #85
  • Serve latest docs at site root, check dead links in README by @bittner in #84
  • Track media files with Git-LFS, move images to docs/media by @bittner in #83
  • Fix docstring markup (reStructuredText ➜ MarkDown) by @bittner in #81
  • Trigger CI workflows on main only, phasing out dev by @bittner in #87
  • Fix broken docs screenshots, skip demo video in CI by @bittner in #88

Full Changelog: 0.3.0...0.4.0

0.3.0 · Smoother and More Conversational · 2026-06-13

Tray Icon & Instant Feedback

This release puts EasySpeak in your GNOME tray — a status indicator with voice deactivate — and makes it feel snappier by speaking feedback in parallel with carrying out your command: the spoken reply now starts playing while the action runs, instead of only after it has finished. It also adds native on-screen displays and chimes for volume and brightness via media keys, and a persistent Piper process that loads the voice model once for faster speech. EasySpeak now owns the full GNOME-extension lifecycle — shipped as package data, staged so a failed refresh can't corrupt an install, and time-bounded against hanging system calls. The interaction model grew more conversational too: it keeps listening between commands without repeating the wake word, handles "stop" gracefully instead of quitting, and gives friendlier misunderstanding feedback — backed by new integration/acceptance test tiers and a 99% coverage floor.

What's Changed

  • feat(apps): add more GNOME apps, handle default terminal by @bittner in #57
  • perf(tts): load the voice model once via a persistent piper process by @bittner in #56
  • refactor(core): new speech module, suppress ALSA error output by @bittner in #58
  • feat(system): native OSD for volume and brightness via media keys by @bittner in #61
  • feat(core): GNOME tray indicator with voice deactivate by @bittner in #59
  • test(extension): extract pure JS helpers and unit-test them by @bittner in #60
  • Improve voice interaction: friendlier feedback, parallel replies, richer commands, hands-free chaining by @bittner in #63

Full Changelog: 0.2.0...0.3.0

0.2.0 · Broader Reach · 2026-06-07

Runs in More Places

EasySpeak broadens where and how it runs: installation now works on Python 3.13 (with dependencies pinned for 3.10), pyaudio ships as a dependency, and a new Nix flake supports development and running on NixOS. This release also makes the Piper TTS model path configurable, auto-installs the MouseGrid GNOME extension on first run, and adds Whisper transcription-latency benchmarks. Config handling was extracted into its own module and host-environment setup moved into the plugins, tidying the codebase alongside steady dependency and security-workflow upkeep.

What's Changed

  • Allow installing on Python 3.13, pin deps for 3.10 by @bittner in #33
  • Add Python package version badge to README by @bittner in #34
  • Add pyaudio as a package dependency by @bittner in #36
  • Update outdated package dependencies (typer-slim ++) by @bittner in #38
  • Update outdated package dependencies by @bittner in #39
  • Run safety workflow also in PRs by @bittner in #40
  • Update outdated dependencies, restrict schedule for check by @bittner in #41
  • Update outdated package dependencies by @bittner in #43
  • Fix missing apt update for apt install by @bittner in #44
  • Update dependencies and actions by @bittner in #45
  • Update outdated package dependencies by @bittner in #49
  • Add Nix flake for development and running on NixOS by @bittner in #51
  • Make Piper TTS model path configurable via env var by @bittner in #52
  • Run performance benchmarks for Whisper transcribe latency by @bittner in #53
  • Extract config module and move host-env setup into plugins by @bittner in #54
  • Fix No plugins directory found error by @gband85 in #47
  • Fix mousegrid error caused by duplicate import by @wkarl in #48

New Contributors

  • @gband85 made their first contribution in #47
  • @wkarl made their first contribution in #48

Full Changelog: 0.1.0...0.2.0

0.1.0 · Foundation · 2026-02-08

Hello, Jarvis

The first release of EasySpeak, published to PyPI as easyspeak-linux: a fully local, Wayland-native voice control for Linux desktops. Say "Hey Jarvis" to drive GNOME hands-free with wake-word activation, a mouse grid, browser control, dictation, and an app launcher — no cloud and no accounts. This release also laid the project's engineering foundation: a clean src layout, a GHA CI pipeline for linting, typing, tests, and an automated PyPI publish, and a first suite of unit tests covering the core engine, CLI, and browser plugin.

What's Changed

  • chore(gitignore): change gitignore file to .gitignore and remove pre-compiled python assets by @tulilirockz in #11
  • Add a Justfile, draft packaging setup, contributing docs by @bittner in #14
  • Organize Python modules with src layout, add first tests by @bittner in #15
  • Add CI pipeline for linting and tests by @bittner in #17
  • Allow all CI jobs to finish, reformat codebase, fix linting by @bittner in #18
  • Fix type check config, make tests run and pass by @bittner in #19
  • Update dependencies (uv.lock) by @bittner in #20
  • Add unit tests for core module (mostly EasySpeak class) by @bittner in #21
  • Run software safety related jobs only once a day by @bittner in #23
  • Refactor application entrypoint (CLI), add tests by @bittner in #22
  • Add tests for browser plugin by @bittner in #25
  • Update outdated package dependencies by @bittner in #26
  • Add tests for dictation plugin by @bittner in #27
  • Add tests for apps plugin by @bittner in #28
  • Add remaining tests for 100% coverage by @bittner in #29
  • Update outdated package dependencies by @bittner in #30
  • Build Python package, configure automatic release by @bittner in #32

New Contributors

  • @tulilirockz made their first contribution in #11
  • @bittner made their first contribution in #14

Full Changelog: 0.1.0