v0.6.1
VocaMac v0.6.1 - Crash fixes + Dvorak paste fix
A focused patch release with two startup/recovery crash fixes, a paste regression on non-QWERTY keyboard layouts, and CI hardening to keep nightly + release pipelines healthy ahead of GitHub's Node 16/20 deprecation.
If you're on v0.6.0, the in-app update checker will offer this release automatically. All users are encouraged to upgrade — every fix in this release addresses a reproducible, user-visible problem.
🐛 Bug Fixes
Critical: Startup crash from misplaced SPM resource bundles (#118, #119)
Some users hit an immediate crash on launch — the app would bounce in the menu bar then disappear, with the system log mentioning Could not load tokenizer assets. The root cause was that SPM resource bundles (notably swift-transformers_Hub.bundle, which holds the GPT-2 / T5 tokenizer fallbacks WhisperKit relies on) were not being staged inside the .app in a layout that Bundle.module could find at runtime.
Fix: The build pipeline now uses xcodebuild and places resource bundles at Contents/Resources/<bundle>.bundle/Contents/Resources/<file> — the canonical location that Bundle.module's xcodebuild accessor resolves to. Bundle layout is now validated automatically in release, nightly, and (as of this release) PR builds, so this class of regression cannot reach a release again.
Critical: SIGSEGV crash when stopping recording after a microphone replug (#121)
A reproducible crash:
- Start recording
- Replug or change the microphone (the engine resets and recovers)
- Click Stop Recording in the popover
- App crashes with
EXC_BAD_ACCESS (SIGSEGV)
Root cause: SwiftUI's _ButtonGesture wraps action closures with MainActor.assumeIsolated(), which on macOS 26 / Swift 6 can read a freed executor reference if the view tree mutates at the same instant the gesture fires — exactly what happens when the device-change handler flips appStatus → .idle and removes the Stop button while the user's click is mid-dispatch.
Fix: All Task { } closures inside Button actions are now Task { @MainActor in }, which binds the task directly to the main actor and skips the implicit assumeIsolated hop. Applied across MenuBarView, UpdateView, OnboardingView, and SettingsView.
Audio engine: stale callback flags after device interruption (#121)
AudioEngine.handleAudioConfigurationChange now also clears silenceCallbackFired and maxDurationCallbackFired when a device-change interruption occurs. Previously these stale true flags meant neither silence detection nor the max-duration limiter would fire on the next recording session after a replug — recordings could run indefinitely.
Paste failure on Dvorak and other non-QWERTY layouts (#123, #125)
Users on Dvorak (and any non-QWERTY layout) reported that VocaMac transcribed audio correctly but never injected the text into the focused field — instead the active field was often cancelled.
Root cause: TextInjector posted a synthetic Cmd+V using the QWERTY hardware keycode for V (9). macOS interprets synthesized keystrokes through the active layout, and on Dvorak keycode 9 produces ., so the system fired Cmd+. (cancel) instead of Cmd+V (paste).
Fix: TextInjector now resolves the virtual keycode for the character v on the currently active ASCII-capable keyboard layout via TISCopyCurrentASCIICapableKeyboardLayoutInputSource + UCKeyTranslate, and posts that keycode. Dvorak, Colemak, AZERTY, and Programmer Dvorak users now paste correctly. A QWERTY fallback is retained for safety.
🛠 CI / Build Pipeline
- GitHub Actions bumped to Node.js 24 compatible versions (#122) —
actions/checkoutv4 → v6,actions/cachev4 → v5,actions/upload-artifactv4 → v7. Resolves the deprecation warnings that began appearing on April 23, 2026 ahead of GitHub's June 2, 2026 forced cutover. - Bundle-layout validation now runs on every PR build (#127) — the
Verify SPM resource bundles are correctly stagedstep (previously only in release & nightly) was backported topr-build.yml, so any future #119-class regression is caught at PR review time, not at release time. - Local-dev tip in
build.shnow points to the correct binary path (#127) — the first-time-setup hint referenced the oldswift buildoutput path that no longer exists since the switch toxcodebuild.
📚 Documentation
- Update-check 403 explainer (#120) — README now explains that the in-app update check can return a GitHub 403 on shared/VPN networks where the unauthenticated rate limit is exhausted by other users on the same egress IP, and how to work around it.
- Release-notes are now drafted out-of-tree (#126) —
AGENTS.mdanddocs/RELEASE.mdcodify a "release notes live on the GitHub Release page, not in the repo" policy so we stop accumulating staleRELEASE_NOTES_v*.mdfiles. The notes you're reading right now are the first release shipped under this policy.
📊 What's Changed
| PR | Type | Description |
|---|---|---|
| #118 | fix | Copy SPM resource bundles to Contents/MacOS/ to prevent startup crash |
| #119 | fix | Keep SPM resource bundles flat in Contents/MacOS to fix startup crash |
| #120 | docs | Explain GitHub 403 update-check error on shared/VPN networks |
| #121 | fix | Task { @MainActor in } in view button actions to prevent SIGSEGV; clear stale AudioEngine callback flags |
| #122 | ci | Bump GitHub Actions to Node.js 24-compatible versions |
| #125 | fix | Paste correctly on Dvorak and other non-QWERTY layouts |
| #126 | docs | Stop committing per-version release notes to the repo |
| #127 | fix | Pre-release hygiene — correct dev binary path and add bundle validation to PR builds |
| #124 | chore | Bump version to 0.6.1 |
🙏 Thanks
- @slatlasdev — for the reliable reproduction steps and the
.ipscrash report that made the SIGSEGV (#121) crash trivial to track down. - @robertmassaioli who reported #123 with crystal-clear repro steps.
- Everyone who hit the first-launch tokenizer crash and patiently helped narrow down the bundle-layout root cause for #118 / #119.
📦 Installation
Download VocaMac-0.6.1-arm64.dmg from the assets below, drag VocaMac to Applications, and launch. Verify the download with checksums.txt if desired:
shasum -a 256 -c checksums.txt --ignore-missingIf you're already on v0.6.0, the in-app update checker will offer this release automatically.
Requirements: macOS 13 (Ventura) or later, Apple Silicon (M1 or later), 8 GB RAM minimum.
Full changelog: v0.6.0...v0.6.1