Summary
Natively 2.0.9 brings the major audio transcription fixes, native module stability improvements, stealth & shortcut hardening, and a wave of under-the-hood quality improvements from merged PRs.
What's New
- Dual-channel STT — system audio and microphone can now connect to the Natively API simultaneously using per-channel session keys (
system/mic), eliminatingconcurrent_session_blockederrors - Screen Recording permission flow — proactive TCC dialog triggered via
desktopCapturer.getSources()before the audio pipeline starts; clear error surfaced when permission isdeniedorrestrictedinstead of silent black frames - Dodo Payments integration — webhook processing with HMAC-SHA256 verification, idempotent replay guard (24 h),
subscription.on_hold/subscription.failedhandling, and correct plan detection via product-ID env vars
Improvements
- LLM resilience — 60 s / 3-retry wrapper for OpenAI and 90 s / 3-retry wrapper for Claude; Natively API falls back to Gemini on failure;
streamChatWithGeminichain now tries Natively first - GoogleSTT proactive restart — pre-emptive stream restart at 4 min 30 s avoids the 5-minute hard-limit gap; improved buffer flush safety
- REST STT upload size — audio resampled to 16 kHz mono before upload, cutting file size ~6× and keeping files under Groq/OpenAI 25 MB limit
- Deepgram reconnect cap — max 10 reconnect attempts to prevent infinite retry loops during outages
- Windows z-order fix —
setAlwaysOnTopre-asserted aftershowInactive()inswitchToOverlay()andshowOverlay()to prevent DWM silently demoting the overlay layer - macOS compositor hide delay — increased from 50 ms to 150 ms so the window is fully removed before screenshot capture, preventing black frames on slower machines
- STT key pre-population — settings panel now correctly restores saved STT provider keys across all providers (Groq, OpenAI, Deepgram, ElevenLabs, Azure, IBM, Soniox)
- Custom provider timeouts — 30 s
AbortControllertimeout added toexecuteCustomProvider()andstreamWithCustom()to prevent indefinite hangs on unresponsive endpoints
Fixes
- Fixed the audio transcription issue — root cause was Deepgram receiving raw PCM without
encoding=linear16in the WebSocket URL, causing immediateupstream_closedwith code 1000 and zero transcription output - Fixed STT over-billing — language/sample-rate reconnects produced short-lived sessions billed as 1 min each; added 30 s minimum threshold for sessions with no Deepgram speech, and changed
Math.ceil→Math.roundfor fairer rounding; duplicate mic-channel billing that doubled every session is now removed - Fixed native module crash —
better-sqlite3rebuilt withelectron-rebuildfor Electron's NMV 130, resolvingNODE_MODULE_VERSION 141 vs 130crashes that broke all DB operations (meetings, RAG, KnowledgeOrchestrator) - Fixed asar stub audio silence —
app.asar.unpackedpath now checked first innativeModuleLoader; added functional smoke-test (getInputDevices()must return an Array) to permanently catch this class of false-pass - Fixed ad-hoc signing order —
codesign --deepon the.appruns first, then.nodebinaries are re-signed with entitlements, preventing--deepfrom stripping the screen-capture entitlement - Fixed keybind registration failure surfacing — when
globalShortcut.register()returnsfalse, akeybinds:registration-failedIPC event is now broadcast to the renderer so the UI can warn the user - Fixed dark mode logo —
force-black-iconCSS class now correctly renders the logo white/faded in dark mode; resolved specificity conflict where opacity was silently overridden - Fixed theme flash on launch — inline
<script>inindex.htmlreadslocalStorageand appliesdata-themesynchronously before the JS bundle loads, eliminating the light/dark flicker on repeat launches - Fixed Natively STT fallback — users with a stored
sttProvider='natively'but no key no longer crash on meeting start; gracefully falls back to GoogleSTT - Fixed
concurrent_session_blockedpermanent lock — removed it from the fatal-error list; server closes the socket andscheduleReconnect()retries correctly after the old session is cleaned up - Integrated several PRs — napi-rs v3 migration for native audio entrypoints, Windows header layout fix, platform-aware shortcut symbols in About section, and various TypeScript type-safety improvements across
electron.d.ts,preload.ts, andipcHandlers.ts
Technical
- Migrated native audio entrypoints to napi-rs v3
ThreadsafeFunctionAPI with err-first(err, arg)callback signatures nativelyapi/server.jscomprehensive rewrite fixing 15 critical bugs (missing imports,ReferenceErrorconstants, session key scoping, HMAC webhook verification, ElevenLabs message normalization, and more)scripts/build-native.js— dynamic Xcode clang version resolution fixes x86_64 cross-compilation linker error on Xcode 16+- Added
NSScreenCaptureUsageDescriptionandNSMicrophoneUsageDescriptiontomac.extendInfofor correct TCC permission dialogs nativelyapi/railway.tomldeployment config added; production smoke-test script (test-prod.sh) included
⚠️ macOS Installation (Unsigned Build)
Download the correct architecture .zip or .dmg file for your device (Apple Silicon or Intel).
If you see "App is damaged":
-
For .zip downloads:
- Move the app to your Applications folder.
- Open Terminal and run:
xattr -cr /Applications/Natively.app
-
For .dmg downloads:
- Open Terminal and run:
xattr -cr ~/Downloads/Natively-2.0.9-arm64.dmg # Or for Intel Macs: xattr -cr ~/Downloads/Natively-2.0.9-x64.dmg
- Install the natively.dmg
- Open Terminal and run:
xattr -cr /Applications/Natively.app
- Open Terminal and run:
⚠️ Windows Installation (Unsigned Build)
When running the installer on Windows, you might see a "Windows protected your PC" warning from Microsoft Defender SmartScreen saying it prevented an unrecognized app from starting.
Since this is an unsigned build, this is expected. You can safely ignore it by clicking More info and then Run anyway.