// KeyboardTextInserter.swift // OSGKeyboard · Keyboard Extension // // Inserts Flow transcripts from the host app and surfaces polish warnings // without re-running LLM polish in the extension. Also tracks the last // voice insertion so the undo button can roll it back safely. import OSGKeyboardShared @MainActor final class KeyboardTextInserter { private let state: KeyboardState private let insertText: (String) -> Void private let deleteBackward: () -> Void private let contextBeforeInput: () -> String? private let scheduleAutoClearError: () -> Void /// Exact string last inserted by voice (including any word-boundary /// separator). Cleared after a successful undo or when the caret no /// longer sits after that text. private var lastInsertedText: String? /// Suppresses availability refresh while we walk `deleteBackward` /// for undo, so intermediate contexts don't flicker the button. private var isUndoing = false init( state: KeyboardState, insertText: @escaping (String) -> Void, deleteBackward: @escaping () -> Void, contextBeforeInput: @escaping () -> String?, scheduleAutoClearError: @escaping () -> Void ) { self.state = state self.insertText = insertText self.deleteBackward = deleteBackward self.contextBeforeInput = contextBeforeInput self.scheduleAutoClearError = scheduleAutoClearError } func handleFlowTranscript( _ delivery: TranscriptionDelivery, replacePrevious: String? = nil ) { let trimmed = delivery.text.trimmingCharacters(in: .whitespacesAndNewlines) guard !trimmed.isEmpty else { state.phase = .idle state.level = 0 return } if let previous = replacePrevious?.trimmingCharacters(in: .whitespacesAndNewlines), !previous.isEmpty, let preceding = contextBeforeInput(), preceding.hasSuffix(previous) { for _ in 0..