Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
342 commits
Select commit Hold shift + click to select a range
7561408
Merge branch 'audit-item-s4m14' into audit-tier1
csmashe Jul 18, 2026
13c32ba
Validate prompt and profile hotkey bindings at edit time (audit §4 M12)
csmashe Jul 18, 2026
21ceb7b
Merge branch 'audit-item-s4m12' into audit-tier1
csmashe Jul 18, 2026
b5478bd
Refuse desktop config writes when the file changed since capture (aud…
csmashe Jul 18, 2026
00adc31
Merge branch 'audit-item-s4m9' into audit-tier1
csmashe Jul 18, 2026
b9fcde6
Track evdev modifiers per device and resync after dropped event strea…
csmashe Jul 18, 2026
6f8e7e0
Merge branch 'audit-item-s4m15' into audit-tier1
csmashe Jul 18, 2026
39ceae1
Gate audio capture stop, reads, and reconfiguration behind per-start …
csmashe Jul 18, 2026
7e3bb25
Merge branch 'audit-item-s5h2' into audit-tier1
csmashe Jul 18, 2026
bfbc1bc
Detect stale desktop integration and offer refresh after hotkey or mo…
csmashe Jul 18, 2026
0db25be
Merge branch 'audit-item-s4m6' into audit-tier1
csmashe Jul 18, 2026
473751c
Observe espeak playback end to end and kill children on cancellation …
csmashe Jul 18, 2026
ef2d2b3
Merge branch 'audit-item-s5m1' into audit-tier1
csmashe Jul 18, 2026
a626390
Restore system audio before the recorder is disposed at shutdown (aud…
csmashe Jul 18, 2026
5212162
Merge branch 'audit-item-s5h3' into audit-tier1
csmashe Jul 18, 2026
3373cb9
Bound GNOME, Hyprland, and Sway helper commands with process-runner t…
csmashe Jul 18, 2026
feffda0
Merge branch 'audit-item-s4m16' into audit-tier1
csmashe Jul 18, 2026
4cee18c
Rebuild the preview stream when the capture device changes before min…
csmashe Jul 18, 2026
d8efb35
Merge branch 'audit-item-s5m3' into audit-tier1
csmashe Jul 18, 2026
d0405db
Preserve per-channel volume balance across audio ducking and restore …
csmashe Jul 18, 2026
35c12ce
Merge branch 'audit-item-s5m11' into audit-tier1
csmashe Jul 18, 2026
4382c56
Finish start feedback before opening dictation capture (audit §5 M2)
csmashe Jul 18, 2026
4e3c1a8
Merge branch 'audit-item-s5m2' into audit-tier1
csmashe Jul 18, 2026
f1e5a7b
Honor the resolved readback language in Linux system TTS with a bound…
csmashe Jul 18, 2026
1be626e
Merge branch 'audit-item-s5m7' into audit-tier1
csmashe Jul 18, 2026
e4c352c
Preserve the saved microphone preference when its identity is missing…
csmashe Jul 18, 2026
685288c
Merge branch 'audit-item-s5m4' into audit-tier1
csmashe Jul 18, 2026
c36b666
Observe Recorder stop persistence and report save failures honestly (…
csmashe Jul 18, 2026
40d6fab
Merge branch 'audit-item-s5m14' into audit-tier1
csmashe Jul 18, 2026
21a9cfe
Retain and retry failed volume and media restoration with bounded pas…
csmashe Jul 18, 2026
d076ee7
Merge branch 'audit-item-s5m12' into audit-tier1
csmashe Jul 18, 2026
fa49429
Pin sound-cue process-runner routing and timeout bounds with regressi…
csmashe Jul 18, 2026
f20afdc
Merge branch 'audit-item-s5m13' into audit-tier1
csmashe Jul 18, 2026
f877dd5
Materialize growing WAV snapshots outside the realtime sample lock (a…
csmashe Jul 18, 2026
ceccac6
Merge branch 'audit-item-s5m5' into audit-tier1
csmashe Jul 18, 2026
2e4a2cc
Make speech playback ownership publication atomic and release hung-pr…
csmashe Jul 18, 2026
bdf778c
Merge branch 'audit-item-s5m8' into audit-tier1
csmashe Jul 18, 2026
504f21f
Carry processing and terminal dictation feedback through the tiling-W…
csmashe Jul 18, 2026
ee5459a
Merge branch 'audit-item-s5m10' into audit-tier1
csmashe Jul 18, 2026
a21817a
Band-limit audio with a windowed-sinc low-pass before downsampling (a…
csmashe Jul 18, 2026
2a44667
Merge branch 'audit-item-s5m6' into audit-tier1
csmashe Jul 18, 2026
ab005db
Track and cancel the actual spd-say utterance with a bounded dispatch…
csmashe Jul 18, 2026
24be062
Merge branch 'audit-item-s5m9' into audit-tier1
csmashe Jul 18, 2026
fa005ce
Stage live restores and apply them transactionally at startup before …
csmashe Jul 18, 2026
4072cd8
Merge branch 'audit-item-s6h3' into audit-tier1
csmashe Jul 18, 2026
6e02faf
Make Linux preferences persistence atomic and stale-snapshot safe (au…
csmashe Jul 18, 2026
67f0165
Merge branch 'audit-item-s6m2' into audit-tier1
csmashe Jul 18, 2026
173bc52
Make caller cancellation authoritative at every ProcessRunner result …
csmashe Jul 19, 2026
1861e58
Merge branch 'audit-item-s6m1' into audit-tier1
csmashe Jul 19, 2026
2540fe1
Bound local HTTP API concurrency and request-body memory (audit §6 M3)
csmashe Jul 19, 2026
a7e0f30
Merge branch 'audit-item-s6m3' into audit-tier1
csmashe Jul 19, 2026
251740b
Resolve the control-socket fallback deterministically under a secured…
csmashe Jul 19, 2026
08c3126
Merge branch 'audit-item-s6m5' into audit-tier1
csmashe Jul 19, 2026
2952c99
Acknowledge record.start before slow startup completes and project th…
csmashe Jul 19, 2026
0c2bd09
Merge branch 'audit-item-s6m6' into audit-tier1
csmashe Jul 19, 2026
a0e8395
Make profile toggles atomic under one service gate and break the reco…
csmashe Jul 19, 2026
9d788ca
Merge branch 'audit-item-s6m4' into audit-tier1
csmashe Jul 19, 2026
4b69bc0
Track CUDA preload per library so a partial preload stays retryable (…
csmashe Jul 19, 2026
064dc01
Merge branch 'audit-item-s6m12' into audit-tier1
csmashe Jul 19, 2026
f273e53
Isolate watch-folder runs into generations with bounded stop drain an…
csmashe Jul 19, 2026
07f7ac3
Merge branch 'audit-item-s6m8' into audit-tier1
csmashe Jul 19, 2026
f94ce66
Refuse to overwrite foreign CLI launchers via ownership classificatio…
csmashe Jul 19, 2026
6ac9bae
Merge branch 'audit-item-s6m14' into audit-tier1
csmashe Jul 19, 2026
0eef077
Gate all control-socket unlinks behind flock ownership of a persisten…
csmashe Jul 19, 2026
532b12b
Merge branch 'audit-item-s6m7' into audit-tier1
csmashe Jul 19, 2026
b7391b1
Require execute permission and socket liveness in capability discover…
csmashe Jul 19, 2026
fdd3c08
Merge branch 'audit-item-s6m13' into audit-tier1
csmashe Jul 19, 2026
35765a8
Harden migration, timer, and clipboard paths against stale-state race…
csmashe Jul 20, 2026
39e6fa8
Harden restore limits, API contracts, and startup socket failure hand…
csmashe Jul 20, 2026
251513c
Clear ReSharper inspections across the solution
csmashe Jul 20, 2026
9d5a19b
Make create-new writes atomically exclusive
csmashe Jul 20, 2026
66c5c13
Store recordings in an owner-only directory
csmashe Jul 20, 2026
f6b570b
Give Google Cloud STT requests headroom beyond the audio limit
csmashe Jul 20, 2026
e7eb1dc
Tighten comments on the recording-safety changes
csmashe Jul 20, 2026
cf6f022
Clear ~68% of ReSharper HINT-level findings across the plugins
csmashe Jul 21, 2026
43f71f5
Update plugin files to correct usage of WithCancellation and trim API…
csmashe Jul 21, 2026
3c611ac
Resolve the warning-level ReSharper findings across plugins
csmashe Jul 21, 2026
980db63
Fix the CA analyzer findings across plugins
csmashe Jul 21, 2026
7f9a8f1
Clear the remaining note-level ReSharper findings across plugins
csmashe Jul 21, 2026
c462eac
Add trailing commas and clear the last ReSharper findings
csmashe Jul 21, 2026
9c59123
Address QA review findings
csmashe Jul 21, 2026
f800833
Fix flaky ProfileService concurrency tests under load
csmashe Jul 21, 2026
18efb7b
Fix hotkey reconcile ordering, DE probe errors, and multipart delimiters
csmashe Jul 21, 2026
f6c3558
Add 134 trailing commas the prior scan target never reported
csmashe Jul 21, 2026
ec14e81
Add the remaining 714 trailing commas and correct the ReSharper record
csmashe Jul 21, 2026
8e46178
Refactor WAV PCM extraction: handle non-standard sizes, support strea…
csmashe Jul 21, 2026
53ee9bf
Implement detachAfterExit parameter in ProcessRunner and related test…
csmashe Jul 22, 2026
4105ac3
Guard the autostart toggle behind desktop-entry ownership
csmashe Jul 25, 2026
c389044
Merge branch 'audit-item-s6m15' into audit-tier1
csmashe Jul 25, 2026
1996b72
Keep the watch-folder queue alive through provider cancellations
csmashe Jul 25, 2026
0f1fce0
Merge branch 'audit-item-s6m9' into audit-tier1
csmashe Jul 25, 2026
e9c9d28
Use case-sensitive path identity in the watch-folder service
csmashe Jul 25, 2026
bfbeef5
Merge branch 'audit-item-s6m10' into audit-tier1
csmashe Jul 25, 2026
5d80679
Verify bundled plugin deployments by content, gated by stat manifests
csmashe Jul 25, 2026
29b4f5b
Merge branch 'audit-item-s6m16' into audit-tier1
csmashe Jul 25, 2026
a4300f5
Bound plugin shutdown and never skip disposal
csmashe Jul 25, 2026
2b566bc
Merge branch 'audit-item-s6m17' into audit-tier1
csmashe Jul 25, 2026
fb49e33
Persist watch-folder fingerprints transactionally with backup recovery
csmashe Jul 25, 2026
97ca98e
Merge branch 'audit-item-s6m11' into audit-tier1
csmashe Jul 25, 2026
16f4214
Marshal plugin capability refreshes to the UI thread and coalesce them
csmashe Jul 25, 2026
48cb9af
Merge branch 'audit-item-s7h3' into audit-tier1
csmashe Jul 25, 2026
ba3744e
Stage the deferred bootstrap with per-stage boundaries and dependencies
csmashe Jul 25, 2026
0852182
Merge branch 'audit-item-s6m18' into audit-tier1
csmashe Jul 25, 2026
ab35ef7
Keep configured TTS and memory preferences separate from availability
csmashe Jul 25, 2026
3ced7cf
Merge branch 'audit-item-s7m2' into audit-tier1
csmashe Jul 25, 2026
ad73752
Isolate and time-bound every third-party plugin settings boundary
csmashe Jul 25, 2026
c0dc9be
Merge branch 'audit-item-s7h4' into audit-tier1
csmashe Jul 25, 2026
b2342db
Contain expected UI I/O and platform failures behind a shared guard
csmashe Jul 25, 2026
69e710d
Merge branch 'audit-item-s7h5' into audit-tier1
csmashe Jul 25, 2026
2b75034
Park the hidden dictation overlay offscreen so it cannot swallow clicks
csmashe Jul 25, 2026
5a3ae1b
Merge branch 'audit-item-s7m3' into audit-tier1
csmashe Jul 25, 2026
076d1be
Gate watch-folder auto-start on plugin bootstrap and retry readiness
csmashe Jul 25, 2026
2d4e9e1
Merge branch 'audit-item-s7m1' into audit-tier1
csmashe Jul 25, 2026
47cc361
Verify focus restoration before recent-transcription auto-paste
csmashe Jul 25, 2026
290e7e8
Merge branch 'audit-item-s7m4' into audit-tier1
csmashe Jul 25, 2026
46499b2
Render History, Dashboard, and About timestamps in local time
csmashe Jul 25, 2026
2aa3b72
Merge branch 'audit-item-s7m5' into audit-tier1
csmashe Jul 25, 2026
205e4a0
Preserve unsaved plugin settings drafts across ambient refreshes
csmashe Jul 25, 2026
a395cf2
Merge branch 'audit-item-s7m6' into audit-tier1
csmashe Jul 25, 2026
ba5f1b1
Cancel onboarding work when the wizard closes or is skipped
csmashe Jul 25, 2026
2f0dbc0
Merge branch 'audit-item-s7m8' into audit-tier1
csmashe Jul 25, 2026
f2e8fa9
Make plugin dropdowns show exactly what Save will send
csmashe Jul 25, 2026
21b7b72
Merge branch 'audit-item-s7m7' into audit-tier1
csmashe Jul 25, 2026
604d0a6
Surface recent-transcription feedback through the real presentation path
csmashe Jul 25, 2026
8fbd5de
Merge branch 'audit-item-s7l1' into audit-tier1
csmashe Jul 25, 2026
f6c6c4e
Relocalize option collections and the tray menu on language change
csmashe Jul 25, 2026
39be586
Merge branch 'audit-item-s7l2' into audit-tier1
csmashe Jul 25, 2026
0c06e75
Drive overlay Timer and Clock widgets from their own ticks
csmashe Jul 25, 2026
799efdc
Merge branch 'audit-item-s7l3' into audit-tier1
csmashe Jul 25, 2026
9391baa
Reject malformed successful responses in the SDK batch parsers
csmashe Jul 25, 2026
cffca4d
Merge branch 'audit-item-s8m1' into audit-tier1
csmashe Jul 25, 2026
89067c0
Honor the transcription helper's plain-text response format
csmashe Jul 25, 2026
aa3af48
Merge branch 'audit-item-s8m2' into audit-tier1
csmashe Jul 25, 2026
db31e19
Coordinate CUDA cache maintenance with a root lock outside the tree
csmashe Jul 25, 2026
7f4a01c
Merge branch 'audit-item-s8m5' into audit-tier1
csmashe Jul 25, 2026
45e1ae9
Fail closed on unverifiable downloads and recover invalid Sherpa models
csmashe Jul 25, 2026
4c9c7c1
Merge branch 'audit-item-s8m3' into audit-tier1
csmashe Jul 25, 2026
fa622db
Define and enforce a grammar for plugin selection identifiers
csmashe Jul 25, 2026
c5f02ef
Merge branch 'audit-item-s8m7' into audit-tier1
csmashe Jul 25, 2026
da5ace7
Fail closed on plugin minimum-host-version compatibility
csmashe Jul 25, 2026
06b0c5c
Merge branch 'audit-item-s8m8' into audit-tier1
csmashe Jul 25, 2026
0f135ad
Derive the shared CUDA cache from the configured asset root and migrate
csmashe Jul 25, 2026
89ccd2c
Merge branch 'audit-item-s8m4' into audit-tier1
csmashe Jul 25, 2026
fbd3b7e
Deliver plugin events ordered, non-reentrant, coalesced, and bounded
csmashe Jul 25, 2026
7185628
Merge branch 'audit-item-s8m9' into audit-tier1
csmashe Jul 25, 2026
4b7ff31
Make plugin manifests authoritative for locality and category
csmashe Jul 25, 2026
39438f7
Merge branch 'audit-item-s12m8' into audit-tier1
csmashe Jul 25, 2026
7279257
Implement Voxtral against Mistral's documented transcription API
csmashe Jul 25, 2026
71f2872
Merge branch 'audit-item-s9h2' into audit-tier1
csmashe Jul 25, 2026
39cbc7f
Implement Gladia's v2 upload, initiate, and poll batch protocol
csmashe Jul 25, 2026
a0105f7
Merge branch 'audit-item-s9h1' into audit-tier1
csmashe Jul 25, 2026
62e0e90
Split additional-provider returns into non-owning role interfaces
csmashe Jul 26, 2026
83c6e22
Merge branch 'audit-item-s8m6' into audit-tier1
csmashe Jul 26, 2026
7c32def
Track realtime pending audio with watermarks instead of one flag
csmashe Jul 26, 2026
c9aa78f
Merge branch 'audit-item-s9h3' into audit-tier1
csmashe Jul 26, 2026
96bdcac
Propagate streaming faults in AssemblyAI, Deepgram, and ElevenLabs
csmashe Jul 26, 2026
587f428
Merge branch 'audit-item-s9h4' into audit-tier1
csmashe Jul 26, 2026
4d2675d
Require terminal events before LLM stream readers return success
csmashe Jul 26, 2026
f8b4840
Merge branch 'audit-item-s9h6' into audit-tier1
csmashe Jul 26, 2026
77176e7
Segment long Google Cloud STT audio into sequential sync requests
csmashe Jul 26, 2026
8274d75
Merge branch 'audit-item-s9m1' into audit-tier1
csmashe Jul 26, 2026
7ccc7e0
Honor cancellation around Sherpa native decode and CUDA provisioning
csmashe Jul 26, 2026
a9fdd0a
Merge branch 'audit-item-s9m3' into audit-tier1
csmashe Jul 26, 2026
b84a0e1
Make concurrent Obsidian saves race-safe with atomic claims and a lock
csmashe Jul 26, 2026
289433d
Merge branch 'audit-item-s9h8' into audit-tier1
csmashe Jul 26, 2026
ac7f7f8
Reject automatic language selection in Google Cloud STT and Sherpa Ca…
csmashe Jul 26, 2026
5bbae18
Merge branch 'audit-item-s9m2' into audit-tier1
csmashe Jul 26, 2026
1d7449b
Normalize OpenAI-Compatible model selections against each server catalog
csmashe Jul 26, 2026
7eb559d
Merge branch 'audit-item-s9m6' into audit-tier1
csmashe Jul 26, 2026
86bf0b4
Route Gemma Local requests through the active model only
csmashe Jul 26, 2026
c79fb7d
Merge branch 'audit-item-s9m4' into audit-tier1
csmashe Jul 26, 2026
ba3eee9
Serialize ChatGPT OAuth refresh behind a single-flight credential gate
csmashe Jul 26, 2026
88a8497
Merge branch 'audit-item-s9m7' into audit-tier1
csmashe Jul 26, 2026
d8dc5b2
Gate xAI streaming on the provider's transcript.created readiness event
csmashe Jul 26, 2026
efc6daa
Merge branch 'audit-item-s9m8' into audit-tier1
csmashe Jul 26, 2026
873d62f
Stop forcing Gemma output into the input language
csmashe Jul 26, 2026
9588390
Merge branch 'audit-item-s9m5' into audit-tier1
csmashe Jul 26, 2026
1e55639
Bound Soniox cleanup with one shared budget instead of two 30s clocks
csmashe Jul 26, 2026
ead5e5b
Merge branch 'audit-item-s9m10' into audit-tier1
csmashe Jul 26, 2026
43021f4
Bound Smallest AI and Reson8 socket disposal with a teardown budget
csmashe Jul 26, 2026
ba7e129
Merge branch 'audit-item-s9m9' into audit-tier1
csmashe Jul 26, 2026
2d17b7f
Store webhook header values as host secrets instead of plaintext
csmashe Jul 26, 2026
3db3d23
Merge branch 'audit-item-s9m11' into audit-tier1
csmashe Jul 26, 2026
0aee26f
Run the CLI test suite in PR CI and release workflows
csmashe Jul 26, 2026
6b61c1d
Merge branch 'audit-item-s11m1' into audit-tier1
csmashe Jul 26, 2026
4eb4b24
Roll back the vector-memory cache when a store fails to persist
csmashe Jul 26, 2026
af477ed
Merge branch 'audit-item-s9m12' into audit-tier1
csmashe Jul 26, 2026
b114ee2
Bound test synchronization waits and add CI hang budgets
csmashe Jul 26, 2026
1bee1aa
Merge branch 'audit-item-s11m7' into audit-tier1
csmashe Jul 26, 2026
0462b2c
Make plugin release publication a draft-first resumable transaction
csmashe Jul 26, 2026
91a12ef
Merge branch 'audit-item-s11m3' into audit-tier1
csmashe Jul 26, 2026
71977da
Gate plugin-tag releases on tests and cover the last untested plugins
csmashe Jul 26, 2026
4fde532
Merge branch 'audit-item-s11m2' into audit-tier1
csmashe Jul 26, 2026
407ec7b
Smoke-test every Linux package before upload or publication
csmashe Jul 26, 2026
dd4d3b5
Merge branch 'audit-item-s11m4' into audit-tier1
csmashe Jul 26, 2026
b037897
Rename the HTTP CLI to typewhisper-cli and retire legacy launchers
csmashe Jul 26, 2026
5969ee3
Merge branch 'item/s10m1' into audit-tier1
csmashe Jul 26, 2026
15a3046
Protect secrets with a random per-user key and authenticated envelopes
csmashe Jul 26, 2026
49b73fe
Merge branch 'item/s6m19' into audit-tier1
csmashe Jul 26, 2026
f0215b2
Serve the local API over Kestrel on TCP plus an owner-only Unix socket
csmashe Jul 27, 2026
e716a9f
Merge branch 'item/s10h2' into audit-tier1
csmashe Jul 27, 2026
3d0ccc4
Give status/models a 10-second budget, distinct timeout errors, and C…
csmashe Jul 27, 2026
ee39546
Merge branch 'item/s10m4' into audit-tier1
csmashe Jul 27, 2026
df055a0
Enforce command-specific CLI grammar and reject unknown task/format v…
csmashe Jul 27, 2026
2308331
Merge branch 'item/s10m5m6' into audit-tier1
csmashe Jul 27, 2026
2800c7b
Transcribe local files via the local-file endpoint; spool stdin to disk
csmashe Jul 27, 2026
c4cd73d
Merge branch 'item/s10m2' into audit-tier1
csmashe Jul 27, 2026
eef91b5
Validate successful API responses and the discovery protocol version
csmashe Jul 27, 2026
20a97d5
Merge branch 'item/s10m3' into audit-tier1
csmashe Jul 27, 2026
4883029
Ship typewhisper-cli in every Linux package with a verified atomic in…
csmashe Jul 27, 2026
187049d
Merge branch 'item/s10h1' into audit-tier1
csmashe Jul 27, 2026
b4deb75
Merge branch 'linux' into audit-tier1
csmashe Jul 27, 2026
67cad66
Fix CI failures and cut 56 MB from the installed footprint
csmashe Jul 27, 2026
b50d83e
Assert the uninstall contract the tarball installer actually promises
csmashe Jul 27, 2026
2ca3c4c
Add trailing commas (part 1 of 2)
csmashe Aug 3, 2026
58bc87a
Add trailing commas (part 2 of 2)
csmashe Aug 3, 2026
ccc5178
Harden shutdown, rollback and teardown paths from the QA review
csmashe Aug 3, 2026
c985cbd
Harden plugin state and atomic writes from review feedback
csmashe Aug 3, 2026
7dc6f20
Correct the _lifecycleLock comment to match what it actually guards
csmashe Aug 3, 2026
6c18bfe
Address review findings across hotkeys, IPC, and preferences
csmashe Aug 3, 2026
f0cddcb
Serialize the settings-test fakes and add the remaining 714 trailing …
csmashe Aug 3, 2026
6e3e392
Discover per-user Flatpak browser launchers via XDG_DATA_DIRS
csmashe Aug 3, 2026
a71604d
Merge reviewed slice 1 (PR #53) into audit-tier1
csmashe Aug 3, 2026
f713da9
Harden persistence, publication, and process cancellation (QA + review)
csmashe Aug 3, 2026
285a82f
Apply QA fixes and clear ReSharper inspections to zero
csmashe Aug 3, 2026
d1eef08
Make the GNOME shortcut writer's list mutations recoverable
csmashe Aug 3, 2026
b671eb6
Centralize XDG data home resolution in XdgPaths
csmashe Aug 3, 2026
b0ac68d
Isolate EntriesChanged subscribers so error reporting cannot throw
csmashe Aug 3, 2026
27f0edf
Refresh Advanced and Appearance sections on the UI thread
csmashe Aug 3, 2026
092744d
Delete the Gladia job when its result_url is unusable
csmashe Aug 3, 2026
1bb924c
Stop a queued section refresh persisting stale settings
csmashe Aug 3, 2026
279104c
Apply the QA and Codex review findings for audit §10
csmashe Aug 3, 2026
3efbb1d
Subscribe to provider changes only after hydration
csmashe Aug 3, 2026
8131897
Merge reviewed slice 2 (PR #54) into audit-tier1
csmashe Aug 3, 2026
b116447
Act on the QA review findings for the tier1-11 slice
csmashe Aug 3, 2026
eea4007
Merge reviewed slice 3 (PR #55) into audit-tier1
csmashe Aug 3, 2026
cd0e603
Merge reviewed slice 4 (PR #56) into audit-tier1
csmashe Aug 3, 2026
59fee44
Merge reviewed slice 5 (PR #57) into audit-tier1
csmashe Aug 3, 2026
3bdf3ce
Merge reviewed slice 6 (PR #58) into audit-tier1
csmashe Aug 3, 2026
edb801a
Merge reviewed slice 7 (PR #59) into audit-tier1
csmashe Aug 3, 2026
6353f1a
Merge reviewed slice 9 (PR #61) into audit-tier1
csmashe Aug 3, 2026
c0bc998
Surface CLI verification launch failures and narrow socket teardown c…
csmashe Aug 3, 2026
bea75b5
Fix QA and review findings across plugins, then clear ReSharper to zero
csmashe Aug 3, 2026
2524c9d
Reconnect the default-device watcher when its subscription ends
csmashe Aug 3, 2026
629166e
Retry a failed initial pactl launch, and pin the reconnect knobs in t…
csmashe Aug 3, 2026
e1dc945
Close job-leak, profile/credential and activation races from review
csmashe Aug 3, 2026
6a99f3b
Merge reviewed slice 10 (PR #62) into audit-tier1
csmashe Aug 3, 2026
12ce67a
Merge reviewed slice 11 (PR #63) into audit-tier1
csmashe Aug 3, 2026
e78c70d
Merge reviewed slice 12 (PR #64) into audit-tier1
csmashe Aug 3, 2026
82d774b
Stop the package smoke gate racing a slow distro mirror
csmashe Aug 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

[*.cs]

# The codebase deliberately uses trailing commas in multiline lists (cleaner diffs);
# tell ReSharper that is the intended style so it stops flagging them for removal.
resharper_csharp_trailing_comma_in_multiline_lists = true

# IDE0066: Convert switch statement to expression
dotnet_diagnostic.ide0066.severity = none

Expand Down
11 changes: 10 additions & 1 deletion .github/workflows/package-dry-run-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
dpkg-dev rpm wget desktop-file-utils
cpio dpkg-dev file rpm wget desktop-file-utils

- name: Resolve dry-run version
id: meta
Expand All @@ -49,7 +49,16 @@ jobs:
- name: Build all Linux packages
run: bash scripts/build-linux-packages.sh "${{ steps.meta.outputs.version }}" dist

- name: Smoke test all Linux packages
# Covers building the two prepared images as well as the smoke runs
# themselves; a throttled distro mirror has pushed the dependency
# download alone past twenty minutes.
timeout-minutes: 45
run: bash scripts/smoke-test-linux-packages.sh "${{ steps.meta.outputs.version }}" dist

- uses: actions/upload-artifact@v7
# Keep the built packages available even when the smoke gate fails so a
# failed dry run can still be diagnosed; the job still reports failure.
if: always()
with:
name: package-dry-run-linux-${{ steps.meta.outputs.version }}
Expand Down
25 changes: 25 additions & 0 deletions .github/workflows/plugins-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,31 @@ jobs:
fetch-depth: 0
persist-credentials: false

- name: Run plugin release transaction regression
shell: pwsh
run: |
$minimumPesterVersion = [version]'5.5.0'
$pester = Get-Module -ListAvailable Pester |
Where-Object Version -ge $minimumPesterVersion |
Sort-Object Version -Descending |
Select-Object -First 1
if (-not $pester) {
Install-Module Pester -RequiredVersion 5.7.1 -Scope CurrentUser -Force
$pester = Get-Module -ListAvailable Pester |
Where-Object Version -ge $minimumPesterVersion |
Sort-Object Version -Descending |
Select-Object -First 1
}
Import-Module $pester.Path -Force

$result = Invoke-Pester `
-Path tests/workflows/PublishPluginReleaseTransaction.Tests.ps1 `
-Output Detailed `
-PassThru
if ($result.FailedCount -gt 0) {
throw "$($result.FailedCount) plugin release transaction test(s) failed."
}

- id: discover
shell: pwsh
run: |
Expand Down
16 changes: 12 additions & 4 deletions .github/workflows/pr-ci-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ concurrency:
jobs:
build-and-test:
runs-on: ubuntu-latest
timeout-minutes: 45

steps:
- uses: actions/checkout@v7
Expand Down Expand Up @@ -50,19 +51,26 @@ jobs:
run: dotnet build src/TypeWhisper.Cli/TypeWhisper.Cli.csproj -c Release --no-restore -bl:artifacts/logs/typewhisper-cli.binlog

- name: Test TypeWhisper.Core
run: dotnet test tests/TypeWhisper.Core.Tests/TypeWhisper.Core.Tests.csproj -c Release --no-build --logger "trx;LogFileName=TypeWhisper.Core.Tests.trx" --results-directory artifacts/test-results
timeout-minutes: 15
run: dotnet test tests/TypeWhisper.Core.Tests/TypeWhisper.Core.Tests.csproj -c Release --no-build --logger "trx;LogFileName=TypeWhisper.Core.Tests.trx" --results-directory artifacts/test-results --blame-hang --blame-hang-timeout 5m --blame-hang-dump-type mini

- name: Test plugin system
run: dotnet test tests/TypeWhisper.PluginSystem.Tests/TypeWhisper.PluginSystem.Tests.csproj -c Release --no-build --logger "trx;LogFileName=TypeWhisper.PluginSystem.Tests.trx" --results-directory artifacts/test-results
timeout-minutes: 15
run: dotnet test tests/TypeWhisper.PluginSystem.Tests/TypeWhisper.PluginSystem.Tests.csproj -c Release --no-build --logger "trx;LogFileName=TypeWhisper.PluginSystem.Tests.trx" --results-directory artifacts/test-results --blame-hang --blame-hang-timeout 5m --blame-hang-dump-type mini

- name: Test TypeWhisper.Linux
run: dotnet test tests/TypeWhisper.Linux.Tests/TypeWhisper.Linux.Tests.csproj -c Release --no-build --logger "trx;LogFileName=TypeWhisper.Linux.Tests.trx" --results-directory artifacts/test-results
timeout-minutes: 15
run: dotnet test tests/TypeWhisper.Linux.Tests/TypeWhisper.Linux.Tests.csproj -c Release --no-build --logger "trx;LogFileName=TypeWhisper.Linux.Tests.trx" --results-directory artifacts/test-results --blame-hang --blame-hang-timeout 5m --blame-hang-dump-type mini

- name: Test TypeWhisper.Cli
timeout-minutes: 15
run: dotnet test tests/TypeWhisper.Cli.Tests/TypeWhisper.Cli.Tests.csproj -c Release --no-build --logger "trx;LogFileName=TypeWhisper.Cli.Tests.trx" --results-directory artifacts/test-results --blame-hang --blame-hang-timeout 5m --blame-hang-dump-type mini

- uses: actions/upload-artifact@v7
if: always()
with:
name: pr-ci-linux-artifacts
path: |
artifacts/logs/*.binlog
artifacts/test-results/*.trx
artifacts/test-results/**
if-no-files-found: ignore
105 changes: 14 additions & 91 deletions .github/workflows/publish-plugins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ jobs:
with:
dotnet-version: '10.0.x'

- name: Test plugin system
timeout-minutes: 15
run: dotnet test tests/TypeWhisper.PluginSystem.Tests/TypeWhisper.PluginSystem.Tests.csproj -c Release -p:DeployBundledLinuxPlugins=false --blame-hang --blame-hang-timeout 5m --blame-hang-dump-type mini

- name: Patch manifest version
shell: pwsh
run: |
Expand Down Expand Up @@ -161,98 +165,17 @@ jobs:
echo "PLUGIN_ID=$pluginId" >> $env:GITHUB_ENV
echo "Created $zipName ($zipSize bytes)"

- name: Create GitHub Release
- name: Publish plugin release transaction
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: pwsh
run: |
$tag = "${{ github.ref_name }}"
gh release create $tag $env:ZIP_NAME `
--title "$env:PROJECT_NAME v$env:PLUGIN_VERSION" `
--notes ""

- name: Update plugins.json on gh-pages
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: pwsh
run: |
$tag = "${{ github.ref_name }}"
$repo = "${{ github.repository }}"
$downloadUrl = "https://github.com/$repo/releases/download/$tag/$env:ZIP_NAME"

git fetch origin gh-pages
git worktree add -B gh-pages gh-pages-work origin/gh-pages

$maxRetries = 5
for ($i = 1; $i -le $maxRetries; $i++) {
try {
Push-Location gh-pages-work
git fetch origin gh-pages
git reset --hard origin/gh-pages

$registry = @(
Get-Content plugins.json | ConvertFrom-Json
)
$updated = $false

for ($j = 0; $j -lt $registry.Count; $j++) {
if ($registry[$j].id -eq $env:PLUGIN_ID) {
$registry[$j].version = $env:PLUGIN_VERSION
$registry[$j].size = [long]$env:ZIP_SIZE
$registry[$j].downloadUrl = $downloadUrl
$updated = $true
Write-Host "Updated $($registry[$j].id) to v$env:PLUGIN_VERSION"
break
}
}

if (-not $updated) {
$manifestPath = Join-Path ".." "plugins/$env:PROJECT_NAME/manifest.json"
$manifest = Get-Content $manifestPath | ConvertFrom-Json

$registry += [pscustomobject]@{
id = $manifest.id
name = $manifest.name
version = $env:PLUGIN_VERSION
minHostVersion = $manifest.minHostVersion
author = $manifest.author
description = $manifest.description
category = $manifest.category
size = [long]$env:ZIP_SIZE
downloadUrl = $downloadUrl
iconSystemName = $manifest.iconSystemName
requiresApiKey = [bool]($manifest.requiresApiKey)
descriptions = $manifest.descriptions
}

Write-Host "Added $env:PLUGIN_ID to registry at v$env:PLUGIN_VERSION"
}

$registry | ConvertTo-Json -Depth 4 | Set-Content plugins.json

# Also copy the ZIP to plugins/ directory on gh-pages
New-Item -ItemType Directory -Path "plugins" -Force | Out-Null
Copy-Item (Join-Path .. $env:ZIP_NAME) "plugins/$env:ZIP_NAME" -Force

git add -A
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

$diff = git diff --cached --quiet 2>&1; $hasChanges = $LASTEXITCODE -ne 0
if ($hasChanges) {
git commit -m "Update $env:PROJECT_NAME to v$env:PLUGIN_VERSION"
git push origin gh-pages
Write-Host "Successfully updated plugins.json (attempt $i)"
} else {
Write-Host "No changes to deploy"
}

Pop-Location
break
} catch {
Pop-Location
if ($i -eq $maxRetries) { throw }
Write-Host "Push failed (attempt $i), retrying in ${i}s..."
Start-Sleep -Seconds $i
}
}
./scripts/publish-plugin-release.ps1 `
-Tag $env:GITHUB_REF_NAME `
-Repository $env:GITHUB_REPOSITORY `
-CommitSha $env:GITHUB_SHA `
-ProjectName $env:PROJECT_NAME `
-PluginVersion $env:PLUGIN_VERSION `
-PluginId $env:PLUGIN_ID `
-ZipPath $env:ZIP_NAME `
-ManifestPath "plugins/$env:PROJECT_NAME/manifest.json"
19 changes: 15 additions & 4 deletions .github/workflows/release-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ jobs:
build:
needs: prepare
runs-on: ubuntu-latest
# 30m unit-test cap + 30m package-smoke cap + 30m setup/build/upload allowance.
timeout-minutes: 90
env:
VERSION: ${{ needs.prepare.outputs.version }}

Expand All @@ -115,19 +117,28 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
dpkg-dev rpm wget desktop-file-utils
cpio dpkg-dev file rpm wget desktop-file-utils

- name: Run unit tests
timeout-minutes: 30
run: |
dotnet restore TypeWhisper.slnx
dotnet build TypeWhisper.slnx -c Release --no-restore -p:Version=${VERSION}
dotnet test tests/TypeWhisper.Core.Tests/TypeWhisper.Core.Tests.csproj -c Release --no-build
dotnet test tests/TypeWhisper.PluginSystem.Tests/TypeWhisper.PluginSystem.Tests.csproj -c Release --no-build
dotnet test tests/TypeWhisper.Linux.Tests/TypeWhisper.Linux.Tests.csproj -c Release --no-build
dotnet test tests/TypeWhisper.Core.Tests/TypeWhisper.Core.Tests.csproj -c Release --no-build --blame-hang --blame-hang-timeout 5m --blame-hang-dump-type mini
dotnet test tests/TypeWhisper.PluginSystem.Tests/TypeWhisper.PluginSystem.Tests.csproj -c Release --no-build --blame-hang --blame-hang-timeout 5m --blame-hang-dump-type mini
dotnet test tests/TypeWhisper.Linux.Tests/TypeWhisper.Linux.Tests.csproj -c Release --no-build --blame-hang --blame-hang-timeout 5m --blame-hang-dump-type mini
dotnet test tests/TypeWhisper.Cli.Tests/TypeWhisper.Cli.Tests.csproj -c Release --no-build --blame-hang --blame-hang-timeout 5m --blame-hang-dump-type mini

- name: Build all Linux packages
run: bash scripts/build-linux-packages.sh "$VERSION" dist

- name: Smoke test all Linux packages
# Covers building the two prepared images as well as the smoke runs
# themselves; a throttled distro mirror has pushed the dependency
# download alone past twenty minutes.
timeout-minutes: 45
run: bash scripts/smoke-test-linux-packages.sh "$VERSION" dist

- uses: actions/upload-artifact@v7
with:
name: release-linux-${{ env.VERSION }}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Press a key, talk, and have clean, punctuated text land in whatever app you're i
- **Personalization** — searchable history, a dictionary with term packs, snippets, and app/URL-matched profiles. History also has an opt-in **Inspect** panel that shows exactly what was sent to the LLM for each entry — the raw→final diff, the exact prompt, injected memory context, and the reply, with local-vs-cloud labelling. See [Profiles](https://github.com/csmashe/typewhisper-linux/wiki/Profiles) and [History](https://github.com/csmashe/typewhisper-linux/wiki/History).
- **Learns from your corrections** in the Wispr-Flow style — when you type over a dictated word in the target app to fix it, TypeWhisper silently learns the correction (via AT-SPI) and auto-applies it to future dictations. A brief toast shows what was learned and offers **Undo**. Off by default (it reads the focused field); enable it under [Dictation](https://github.com/csmashe/typewhisper-linux/wiki/Dictation) settings, and review or remove learned entries in the [Dictionary](https://github.com/csmashe/typewhisper-linux/wiki/Dictionary).
- **A localized interface** — English, German, Spanish, or Russian, switched live (or Auto, to follow your system locale). See [General Settings](https://github.com/csmashe/typewhisper-linux/wiki/General-Settings).
- **Automation** — a local [HTTP API](https://github.com/csmashe/typewhisper-linux/wiki/HTTP-API) and a `typewhisper` [CLI](https://github.com/csmashe/typewhisper-linux/wiki/CLI) client (currently built from source; release packages don't yet bundle the CLI binary).
- **Automation** — a local [HTTP API](https://github.com/csmashe/typewhisper-linux/wiki/HTTP-API) and an installable `typewhisper` [CLI](https://github.com/csmashe/typewhisper-linux/wiki/CLI).
- **Desktop integration** — tray icon, XDG autostart, single-instance handoff, and a user-level installer. See [Desktop Integration](https://github.com/csmashe/typewhisper-linux/wiki/Desktop-Integration).

Everything here is Linux-specific work adapted from the upstream macOS/Windows project: Wayland/X11 global hotkeys, compositor-native window and URL detection, session audio handling, and Linux packaging. The deep how-and-why for each lives in the wiki — start with [Wayland Notes](https://github.com/csmashe/typewhisper-linux/wiki/Wayland-Notes) if you're on Wayland.
Expand Down
34 changes: 34 additions & 0 deletions TypeWhisper.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,38 @@
<Project Path="tests/TypeWhisper.PluginSystem.Tests/TypeWhisper.PluginSystem.Tests.csproj"/>
<Project Path="tests/TypeWhisper.Cli.Tests/TypeWhisper.Cli.Tests.csproj"/>
</Folder>
<Folder Name="/plugins/">
<Project Path="plugins/TypeWhisper.Plugin.AssemblyAi/TypeWhisper.Plugin.AssemblyAi.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Cerebras/TypeWhisper.Plugin.Cerebras.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Claude/TypeWhisper.Plugin.Claude.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.CloudflareAsr/TypeWhisper.Plugin.CloudflareAsr.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Cohere/TypeWhisper.Plugin.Cohere.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Deepgram/TypeWhisper.Plugin.Deepgram.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.ElevenLabs/TypeWhisper.Plugin.ElevenLabs.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.FileMemory/TypeWhisper.Plugin.FileMemory.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Fireworks/TypeWhisper.Plugin.Fireworks.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Gemini/TypeWhisper.Plugin.Gemini.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.GemmaLocal/TypeWhisper.Plugin.GemmaLocal.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Gladia/TypeWhisper.Plugin.Gladia.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.GoogleCloudStt/TypeWhisper.Plugin.GoogleCloudStt.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Groq/TypeWhisper.Plugin.Groq.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Linear/TypeWhisper.Plugin.Linear.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Obsidian/TypeWhisper.Plugin.Obsidian.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.OpenAi/TypeWhisper.Plugin.OpenAi.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.OpenAiCompatible/TypeWhisper.Plugin.OpenAiCompatible.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.OpenAiVectorMemory/TypeWhisper.Plugin.OpenAiVectorMemory.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.OpenRouter/TypeWhisper.Plugin.OpenRouter.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Qwen3Stt/TypeWhisper.Plugin.Qwen3Stt.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Reson8/TypeWhisper.Plugin.Reson8.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Script/TypeWhisper.Plugin.Script.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.SherpaOnnx/TypeWhisper.Plugin.SherpaOnnx.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.SmallestAi/TypeWhisper.Plugin.SmallestAi.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Soniox/TypeWhisper.Plugin.Soniox.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Speechmatics/TypeWhisper.Plugin.Speechmatics.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.SupertonicTts/TypeWhisper.Plugin.SupertonicTts.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Voxtral/TypeWhisper.Plugin.Voxtral.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Webhook/TypeWhisper.Plugin.Webhook.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.WhisperCpp/TypeWhisper.Plugin.WhisperCpp.csproj"/>
<Project Path="plugins/TypeWhisper.Plugin.Xai/TypeWhisper.Plugin.Xai.csproj"/>
</Folder>
</Solution>
Loading
Loading