feat: initial release v0.1.0
- Custom Keyboard Extension with push-to-talk UI - iOS 26 SpeechAnalyzer + DictationTranscriber (iOS 18 SF fallback) - OpenAI-compatible LLM client (4 built-in providers + custom) - 3-page onboarding flow + provider config UI - App Group shared storage for cross-process config - 8s LLM timeout with raw-transcript fallback - App Store privacy manifests for both targets - SwiftLint + XcodeGen + GitHub Actions CI - Unit tests (4/4 passing)
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
// AppGroupStore.swift
|
||||
// OSGKeyboard · Shared
|
||||
//
|
||||
// Convenience wrapper around App Group UserDefaults for non-Published reads.
|
||||
// Used by the keyboard extension (no SwiftUI) to read config without
|
||||
// instantiating an ObservableObject.
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct AppGroupStore: @unchecked Sendable {
|
||||
public let defaults: UserDefaults
|
||||
|
||||
public init(defaults: UserDefaults = AppGroup.defaults) {
|
||||
self.defaults = defaults
|
||||
}
|
||||
|
||||
public var providerId: String {
|
||||
defaults.string(forKey: "config.providerId") ?? "openai"
|
||||
}
|
||||
|
||||
public var baseURL: String {
|
||||
defaults.string(forKey: "config.baseURL") ?? LLMProvider.provider(id: "openai").defaultBaseURL
|
||||
}
|
||||
|
||||
public var apiKey: String {
|
||||
defaults.string(forKey: "config.apiKey") ?? ""
|
||||
}
|
||||
|
||||
public var model: String {
|
||||
defaults.string(forKey: "config.model") ?? LLMProvider.provider(id: "openai").defaultModel
|
||||
}
|
||||
|
||||
public var systemPrompt: String {
|
||||
defaults.string(forKey: "config.systemPrompt")
|
||||
?? "You are a voice-input polishing assistant. Rewrite the user's dictation as clean written text. Preserve intent. Add punctuation and structure. Do not invent facts. Output in the same language as the input."
|
||||
}
|
||||
|
||||
public func makeClient() -> LLMClient {
|
||||
OpenAICompatibleClient(
|
||||
baseURL: baseURL,
|
||||
apiKey: apiKey,
|
||||
model: model
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user