feat(macos): local ASR model manager, menu-bar polish, and release 0.5.2

Adds a bundled local ASR model catalog for the macOS app with one-click
Sherpa Qwen3 / SenseVoice downloads (pause/resume, inline actions) and a
shared model storage directory used by MLX Qwen3. Fixes the light-mode
sidebar material and makes the menu-bar icon follow the system appearance
with a refreshed status mark. Renames the built product to OSGKeyboard.app.

Bumps version to 0.5.2 (build 19).
This commit is contained in:
Rocky
2026-07-09 08:55:37 +08:00
parent c2f07bd8d2
commit 200265fbd6
50 changed files with 4666 additions and 266 deletions
@@ -111,4 +111,29 @@ extension PersonalDictionary {
if hasNonASCII { return "zh" }
return "en"
}
/// Alias canonical term pairs for deterministic post-ASR correction.
/// Sorted longest-alias-first by the caller (`LocalASRTranscriptCorrector`).
public func localCorrectionPairs() -> [LocalASRCorrectionPair] {
var seen = Set<String>()
var pairs: [LocalASRCorrectionPair] = []
for entry in effectiveEntries {
let term = entry.term.trimmingCharacters(in: .whitespacesAndNewlines)
guard !term.isEmpty else { continue }
for alias in entry.aliases {
let trimmed = alias.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else { continue }
guard trimmed.caseInsensitiveCompare(term) != .orderedSame else { continue }
let key = "\(trimmed.lowercased())|\(term.lowercased())"
guard seen.insert(key).inserted else { continue }
pairs.append(LocalASRCorrectionPair(alias: trimmed, term: term))
}
}
return pairs.sorted { lhs, rhs in
if lhs.alias.count != rhs.alias.count {
return lhs.alias.count > rhs.alias.count
}
return lhs.alias.localizedCaseInsensitiveCompare(rhs.alias) == .orderedAscending
}
}
}