fix: actually delete Qwen3 cache when user removes the model#91
Closed
mvanhorn wants to merge 237 commits into
Closed
fix: actually delete Qwen3 cache when user removes the model#91mvanhorn wants to merge 237 commits into
mvanhorn wants to merge 237 commits into
Conversation
Fix overlay constraint crash
Models section shows each model with loaded/not loaded status. Taller settings window (580px) to fit all sections. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Shows when any model isn't loaded. Downloads WhisperKit and/or cleanup models directly from Settings — no need to re-run onboarding. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
LLM.swift's bundled llama.cpp doesn't support Qwen3/3.5 architecture. Reverted to Qwen 2.5 1.5B + 3B which work reliably. Will upgrade when LLM.swift updates its llama.cpp. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Info.plist was still at v1.1 so Sparkle thought the "update" was the same version. Now properly at v1.3 build 4. Fixes #2. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Improve post-paste learning via Accessibility
Picker in Settings under Input section. Switching models triggers re-download and reload. Default remains small.en for accuracy. tiny.en is ~75 MB and much faster for shorter recordings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…oggle) Matches the original Ghost Pepper behavior. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Input Monitoring prompt doesn't reliably show the system dialog for debug-signed apps. Now attempts to start the hotkey monitor even without it — Accessibility alone is sufficient for Control key. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fixed codesign verification failure reported in #4. Now verifies signature after extracting from DMG before release. Also includes: speech model picker, default Control shortcuts, non-blocking Input Monitoring check. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
macOS kills the app after Screen Recording is granted but doesn't relaunch it. Now spawns a background process that reopens the app after 3 seconds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace no-audio modal with status pill
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Addresses #5 — users should know about local transcript log and auto-launch behavior. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
File-based logging was replaced by in-memory DebugLogStore. Nothing is written to disk. Updated disclosure accordingly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
No longer blocks Continue button. Shown as "(optional)" with a bordered (not prominent) Enable button. Users can skip it and enable later in Settings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Matches WhisperFlow and other dictation tools. Toggle is Right Command + Right Option + Space. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Supports Spanish and 90+ other languages. Same size as small.en. Users can tweak the cleanup prompt for their language's filler words. Addresses #6. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This reverts commit ad68a2e.
Reduce transcription latency and improve speaker tagging
…idebar, detect meeting name & attendees - Inline summary prompt editor with model picker on Summary tab (click "Customize") - "Imported from Granola" badge on imported meeting files - Granola files show green import icon in sidebar, no speaker badges on transcript - Resizable sidebar (drag divider, 160-400px range) - Sidebar open by default when Meetings window opens - "Detect" button grabs meeting name from Zoom/Teams window title + OCR attendees - Auto-detect scans known meeting apps even for manual recordings - Attendee OCR retries at 3s, 15s, 30s, 60s to catch late joiners - Attendees accumulate across retries (no duplicates) - Title auto-update only marks as done on success (retries on failure) - "Zoom Meeting" cleaned from window titles Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rowser meetings - Test dictation now uses selected mic (was always using system default) - Settings mic picker initializes from saved selection, not system default - Detect button activates meeting app (including browsers) before OCR - Added browser bundle IDs (Brave, Chrome, Arc, Safari, Firefox) for Google Meet detection - Falls back to frontmost non-Ghost Pepper app if no known meeting app found - Attendee chips UI instead of plain text - Debug logging for attendee OCR capture - Cleaned "Zoom Meeting" from window titles Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- One-time migration: enables meetingTranscriptEnabled for existing users (detects update by checking if selectedCleanupModelKind exists but meetingTranscriptEnabled was never set) - Shows "What's New" NSAlert on first launch after update with "Open Meetings" and "Got It" buttons - Persists hasSeenMeetingTranscriptAnnouncement to only show once - Fix: Settings mic picker initializes from saved selection, not system default - Fix: test dictation targets selected mic device - Fix: prioritize native Zoom over browsers for Detect button - Fix: filter out ZM_ internal Zoom windows from title detection - Fix: strip pronouns from attendee names (she/her, he/him, they/them) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- UpdaterController checks appcast XML 15s after launch to compare versions - Menu bar dropdown shows 'Update Available — Install Now' in orange when update found - Sparkle still handles the actual update dialog and installation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ection Fix Whisper auto-detect defaulting to English for non-English speech
- OAuth 2.0 PKCE flow for desktop apps (no client secret needed) - Reads calendar.events.readonly scope — just event titles, attendees, times - When recording starts, checks calendar for current/upcoming event and auto-populates meeting title and attendee list - Calendar data takes priority over OCR detection (more reliable) - "Connect Google Calendar" button in Settings > Meeting Transcript - Token stored locally in UserDefaults, refreshes automatically - URL scheme handler for OAuth callback (com.github.matthartman.ghostpepper://) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lendar Security improvement: removed the local HTTP server (127.0.0.1:8089) that briefly opened a port during OAuth sign-in. Now uses Google's OOB redirect flow — user copies the auth code from Google and pastes it into Settings. No open ports, no network exposure, same result. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The .qwen3AsrInt8 branch of removeCachedModelFiles(for:) was a no-op
("handled by FluidAudio internally"). modelIsCached(for:) however does
probe the cache directory directly, so after a "remove" click the cache
files are still on disk and the model reappears as "Loaded" on the next
state refresh.
Mirror the parakeetV3 handling: call removeItem(at:) on
Qwen3AsrModels.defaultCacheDirectory(variant: .int8) under the same
#available(macOS 15, iOS 18, *) guard that modelIsCached uses.
Fixes #69
testDeleteCachedQwen3ModelRemovesCacheDirectory verifies the actual filesystem behavior fixed in #69 — pre-populates the Qwen3 int8 cache directory with a placeholder, calls deleteCachedModel, and asserts the directory is gone afterwards. Uses XCTSkipIf when real Qwen3 models are already present so we don't wipe a user's local install. testDeleteCachedQwen3ModelNotifiesObservers covers the publish path unconditionally so the regression is still detectable when the filesystem assertion is skipped. Adds `import FluidAudio` to the test module so we can address Qwen3AsrModels and the .int8 variant directly. Refs #69
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
parakeetV3is handled in the same switch: callQwen3AsrModels.defaultCacheDirectory(variant: .int8)andFileManager.default.removeItem(at:)under the same#available(macOS 15, iOS 18, *)guard thatmodelIsCachedusesWhy this fixes #69
removeCachedModelFiles(for:)inGhostPepper/Transcription/ModelManager.swifthad this no-op for Qwen3:It does nothing. The companion
modelIsCached(for:)(same file) DOES probe the actual cache directory:So:
deleteCachedModel(_:)->removeCachedModelFiles(for:)-> Qwen3 case is no-op..idle, UI shows "Removing...".modelIsCachedreturns true (cache files still on disk), so the model reappears as "Loaded" with no error.The fix is a 4-line edit to actually delete the cache directory.
Test Plan
xcodebuild ... build: passes.xcodebuild ... test: 190 unit tests pass on this branch.main(5 tests underGhostPepperTests/testAppStateArchives*andtestFluidAudioRecordingUsesSpeakerFilteringSession) reproduce on upstream/main without this change. They look environment-related (Index out of rangeafterXCTAssertEqual ("0") != ("1")) and are unrelated to model removal. Happy to look at those separately if useful.Qwen3AsrModels.defaultCacheDirectory(variant: .int8)is deleted and the model row no longer reappears as "Loaded" on the next state refresh.Closes #69