From 60904811cbc854b499febce077a27fd78800317a Mon Sep 17 00:00:00 2001 From: Shreeraman A K <16458670+shreeraman96@users.noreply.github.com> Date: Sun, 26 Jul 2026 11:59:51 -0700 Subject: [PATCH 1/4] feat: accept Voice Memos drags and batch file transcription (#219) - AppKit promise-aware drop target (SwiftUI onDrop cannot receive file promises): concrete URLs + file promises, resolved off-main via modern receiver, legacy promise API, and raw pasteboard data fallbacks - BatchTranscriptionCoordinator: sequential per-item state machine with cancellation, staging cleanup, and batch/dictation arbitration - App-level FileTranscriptionSession so in-flight work survives navigation - Multi-select file picker; batch progress UI with per-item status --- Fluid.xcodeproj/project.pbxproj | 8 + Sources/Fluid/ContentView.swift | 9 + .../BatchTranscriptionCoordinator.swift | 218 +++++++ .../Services/FileTranscriptionSession.swift | 76 +++ .../MeetingTranscriptionService.swift | 2 + .../Fluid/UI/MeetingTranscriptionView.swift | 248 ++++++-- Sources/Fluid/UI/PromiseAwareDropView.swift | 544 ++++++++++++++++++ Sources/Fluid/UI/PromiseDropSupport.swift | 139 +++++ .../BatchTranscriptionCoordinatorTests.swift | 384 +++++++++++++ .../PromiseDropSupportTests.swift | 171 ++++++ 10 files changed, 1760 insertions(+), 39 deletions(-) create mode 100644 Sources/Fluid/Services/BatchTranscriptionCoordinator.swift create mode 100644 Sources/Fluid/Services/FileTranscriptionSession.swift create mode 100644 Sources/Fluid/UI/PromiseAwareDropView.swift create mode 100644 Sources/Fluid/UI/PromiseDropSupport.swift create mode 100644 Tests/FluidDictationIntegrationTests/BatchTranscriptionCoordinatorTests.swift create mode 100644 Tests/FluidDictationIntegrationTests/PromiseDropSupportTests.swift diff --git a/Fluid.xcodeproj/project.pbxproj b/Fluid.xcodeproj/project.pbxproj index 2b135c8c..b6f428bd 100644 --- a/Fluid.xcodeproj/project.pbxproj +++ b/Fluid.xcodeproj/project.pbxproj @@ -19,6 +19,8 @@ 272BFB5CB271489892CAE50C /* TemperatureSupportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 980330F3CE464336ADCE3E23 /* TemperatureSupportTests.swift */; }; A62300000000000000000002 /* AudioBufferConverterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A62300000000000000000001 /* AudioBufferConverterTests.swift */; }; C0DE63600000000000000002 /* AudioEngineRetirementDrainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DE63600000000000000001 /* AudioEngineRetirementDrainTests.swift */; }; + A62300000000000000000022 /* BatchTranscriptionCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A62300000000000000000021 /* BatchTranscriptionCoordinatorTests.swift */; }; + A62300000000000000000032 /* PromiseDropSupportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A62300000000000000000031 /* PromiseDropSupportTests.swift */; }; 7CDB0A2F2F3C4D5600FB7CAD /* dictation_fixture.wav in Resources */ = {isa = PBXBuildFile; fileRef = 7CDB0A2B2F3C4D5600FB7CAD /* dictation_fixture.wav */; }; 7CDB0A302F3C4D5600FB7CAD /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7CDB0A2C2F3C4D5600FB7CAD /* XCTest.framework */; }; 7CE006BD2E80EBE600DDCCD6 /* AppUpdater in Frameworks */ = {isa = PBXBuildFile; productRef = 7CE006BC2E80EBE600DDCCD6 /* AppUpdater */; }; @@ -54,6 +56,8 @@ 980330F3CE464336ADCE3E23 /* TemperatureSupportTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemperatureSupportTests.swift; sourceTree = ""; }; A62300000000000000000001 /* AudioBufferConverterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioBufferConverterTests.swift; sourceTree = ""; }; C0DE63600000000000000001 /* AudioEngineRetirementDrainTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioEngineRetirementDrainTests.swift; sourceTree = ""; }; + A62300000000000000000021 /* BatchTranscriptionCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatchTranscriptionCoordinatorTests.swift; sourceTree = ""; }; + A62300000000000000000031 /* PromiseDropSupportTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromiseDropSupportTests.swift; sourceTree = ""; }; 7C078D8F2E3B339200FB7CAC /* FluidVoice Debug.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "FluidVoice Debug.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 7C91B0022F42AA0100C0DEF0 /* HotkeyShortcutTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HotkeyShortcutTests.swift; sourceTree = ""; }; 7CDB0A202F3C4D5600FB7CAD /* FluidDictationIntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FluidDictationIntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -132,6 +136,8 @@ 980330F3CE464336ADCE3E23 /* TemperatureSupportTests.swift */, A62300000000000000000001 /* AudioBufferConverterTests.swift */, C0DE63600000000000000001 /* AudioEngineRetirementDrainTests.swift */, + A62300000000000000000021 /* BatchTranscriptionCoordinatorTests.swift */, + A62300000000000000000031 /* PromiseDropSupportTests.swift */, ); path = FluidDictationIntegrationTests; sourceTree = ""; @@ -291,6 +297,8 @@ 272BFB5CB271489892CAE50C /* TemperatureSupportTests.swift in Sources */, A62300000000000000000002 /* AudioBufferConverterTests.swift in Sources */, C0DE63600000000000000002 /* AudioEngineRetirementDrainTests.swift in Sources */, + A62300000000000000000022 /* BatchTranscriptionCoordinatorTests.swift in Sources */, + A62300000000000000000032 /* PromiseDropSupportTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Sources/Fluid/ContentView.swift b/Sources/Fluid/ContentView.swift index 2410fd45..9af31bf0 100644 --- a/Sources/Fluid/ContentView.swift +++ b/Sources/Fluid/ContentView.swift @@ -3036,6 +3036,15 @@ struct ContentView: View { /// Capture app context at start to avoid mismatches if the user switches apps mid-session private func startRecording() { + // File-transcription batches drive the same shared ASR model; starting + // dictation mid-batch would run concurrent inference through one model. + guard !FileTranscriptionSession.isBatchTranscribing else { + DebugLogger.shared.warning( + "Dictation blocked: batch file transcription in progress", + source: "ContentView" + ) + return + } let model = SettingsStore.shared.selectedSpeechModel DebugLogger.shared.info( "ContentView: startRecording() for model=\(model.displayName), supportsStreaming=\(model.supportsStreaming)", diff --git a/Sources/Fluid/Services/BatchTranscriptionCoordinator.swift b/Sources/Fluid/Services/BatchTranscriptionCoordinator.swift new file mode 100644 index 00000000..e3fb8337 --- /dev/null +++ b/Sources/Fluid/Services/BatchTranscriptionCoordinator.swift @@ -0,0 +1,218 @@ +import Combine +import Foundation + +/// Coordinates sequential transcription of a batch of audio files (issue #219). +/// +/// The coordinator owns per-item state for multi-file transcription: strict sequential +/// processing in enqueue order, per-item success/failure/no-speech outcomes, cooperative +/// cancellation of the in-flight file, staging-directory cleanup after each item finishes, +/// and batch start/end hooks for dictation arbitration. All stored closures are invoked on +/// the main actor. +@MainActor +final class BatchTranscriptionCoordinator: ObservableObject { + /// A transcription request for a single audio file. + struct Request { + let url: URL + let stagingDir: URL? + + init(url: URL, stagingDir: URL? = nil) { + self.url = url + self.stagingDir = stagingDir + } + } + + /// Per-item transcription outcome. + enum Status { + case pending + case transcribing + case completed(TranscriptionResult) + case noSpeech + case failed(String) + case cancelled + } + + /// Tracked state for a single enqueued file. + struct Item: Identifiable { + let id: UUID + let url: URL + let stagingDir: URL? + var status: Status + } + + @Published private(set) var items: [Item] = [] + @Published private(set) var isRunning: Bool = false + + private let transcribe: @MainActor (URL) async throws -> TranscriptionResult + private let onBatchStart: @MainActor () -> Void + private let onBatchEnd: @MainActor () -> Void + + private var batchTask: Task? + /// Published so the UI can show a "Cancelling…" state: pending items stop + /// immediately, but the in-flight item may run to completion (the native + /// provider transcription has no interruption point). + @Published private(set) var isCancelRequested: Bool = false + + private var isCancelled: Bool = false + private var idleWaiters: [CheckedContinuation] = [] + + init( + transcribe: @escaping @MainActor (URL) async throws -> TranscriptionResult, + onBatchStart: @escaping @MainActor () -> Void = {}, + onBatchEnd: @escaping @MainActor () -> Void = {} + ) { + self.transcribe = transcribe + self.onBatchStart = onBatchStart + self.onBatchEnd = onBatchEnd + } + + // MARK: - Enqueue + + /// Append requests and start a sequential processing batch if idle. Enqueuing while a + /// batch is running appends to the live batch. + func enqueue(_ requests: [Request]) { + for request in requests { + self.items.append( + Item( + id: UUID(), + url: request.url, + stagingDir: request.stagingDir, + status: .pending + ) + ) + } + + if self.batchTask == nil { + self.startBatch() + } + } + + // MARK: - Cancellation + + /// Cancel the in-flight transcription and every still-pending item. No-op when idle. + func cancel() { + guard self.batchTask != nil else { return } + + self.isCancelled = true + self.isCancelRequested = true + + for index in 0.. TranscriptionResult + private var forwarder: AnyCancellable? + + init(transcribe: @escaping @MainActor (URL) async throws -> TranscriptionResult) { + self.transcribe = transcribe + } + + func enqueue(_ requests: [BatchTranscriptionCoordinator.Request]) { + if self.coordinator == nil { + let coordinator = BatchTranscriptionCoordinator(transcribe: self.transcribe) + self.forwarder = coordinator.objectWillChange + .sink { [weak self] _ in self?.objectWillChange.send() } + self.coordinator = coordinator + } + self.coordinator?.enqueue(requests) + } + + func clear() { + // Never orphan a running batch: without this, dropping the coordinator + // would leave it transcribing invisibly with no way to reach it. + self.coordinator?.cancel() + self.forwarder?.cancel() + self.forwarder = nil + self.coordinator = nil + } +} diff --git a/Sources/Fluid/Services/MeetingTranscriptionService.swift b/Sources/Fluid/Services/MeetingTranscriptionService.swift index 67d1eede..5a69072a 100644 --- a/Sources/Fluid/Services/MeetingTranscriptionService.swift +++ b/Sources/Fluid/Services/MeetingTranscriptionService.swift @@ -216,6 +216,7 @@ final class MeetingTranscriptionService: ObservableObject { source: "MeetingTranscriptionService" ) + try Task.checkCancellation() let nativeResult = try await provider.transcribeFile(at: fileURL) let processingTime = Date().timeIntervalSince(startTime) let result = TranscriptionResult( @@ -284,6 +285,7 @@ final class MeetingTranscriptionService: ObservableObject { self.currentStatus = duration > 0 ? "Transcribing audio (\(Int(duration))s)..." : "Transcribing audio..." while currentFrame < audioFile.length { + try Task.checkCancellation() let remainingFrames = AVAudioFrameCount(audioFile.length - currentFrame) let framesToRead = min(sourceFramesPerChunk, remainingFrames) diff --git a/Sources/Fluid/UI/MeetingTranscriptionView.swift b/Sources/Fluid/UI/MeetingTranscriptionView.swift index bea63c77..5364c1cd 100644 --- a/Sources/Fluid/UI/MeetingTranscriptionView.swift +++ b/Sources/Fluid/UI/MeetingTranscriptionView.swift @@ -1,16 +1,22 @@ +import Combine import SwiftUI import UniformTypeIdentifiers struct MeetingTranscriptionView: View { let asrService: ASRService - @StateObject private var transcriptionService: MeetingTranscriptionService + // Owned by FileTranscriptionSession (app-level) so in-flight transcriptions + // survive this view being destroyed by sidebar navigation. + @ObservedObject private var transcriptionService: MeetingTranscriptionService + @ObservedObject private var batchHolder: BatchCoordinatorHolder @ObservedObject private var fileHistoryStore = FileTranscriptionHistoryStore.shared @State private var selectedFileURL: URL? @Environment(\.theme) private var theme init(asrService: ASRService) { self.asrService = asrService - _transcriptionService = StateObject(wrappedValue: MeetingTranscriptionService(asrService: asrService)) + let session = FileTranscriptionSession.shared + self.transcriptionService = session.service + self.batchHolder = session.batchHolder } @State private var showingFilePicker = false @@ -58,18 +64,18 @@ struct MeetingTranscriptionView: View { // File Selection Card self.fileSelectionCard - // Progress Card (only show when transcribing) - if self.transcriptionService.isTranscribing { + // Progress Card (only show when transcribing outside a batch) + if self.transcriptionService.isTranscribing && !self.isBatchActive { self.progressCard } - // Results Card (only show when we have results) - if let result = transcriptionService.result { + // Results Card (only show when we have results outside a batch) + if let result = transcriptionService.result, !self.isBatchActive { self.resultsCard(result: result) } - // Error Card (only show when we have an error) - if let error = transcriptionService.error { + // Error Card (only show when we have a single-file error) + if let error = transcriptionService.error, !self.isBatchActive { self.errorCard(error: error) } @@ -78,6 +84,11 @@ struct MeetingTranscriptionView: View { self.dropErrorCard(message: message) } + // Batch transcription progress/results + if self.isBatchActive { + self.batchSection + } + // Recent transcriptions (persisted history) if !self.fileHistoryStore.entries.isEmpty { Divider() @@ -89,6 +100,16 @@ struct MeetingTranscriptionView: View { } } .frame(maxWidth: .infinity, maxHeight: .infinity) + // Overlay, not background: AppKit's drag-target search walks views + // front-to-back, so the drop target must sit above the SwiftUI content. + // Its hitTest returns nil, so clicks pass through to the UI beneath. + .overlay( + PromiseAwareDropView( + onTargetedChange: { self.isDropTargeted = $0 }, + onFiles: { self.handleIncomingFiles($0) }, + onError: { self.dropErrorMessage = $0 } + ) + ) .background(self.theme.palette.windowBackground) .overlay(alignment: .topTrailing) { if self.showingCopyConfirmation { @@ -178,7 +199,7 @@ struct MeetingTranscriptionView: View { .padding(.vertical, 12) } .buttonStyle(.borderedProminent) - .disabled(self.transcriptionService.isTranscribing) + .disabled(self.transcriptionService.isTranscribing || self.isBatchActive) } else { // File picker button – whole area is tappable; supports drag-and-drop @@ -214,22 +235,16 @@ struct MeetingTranscriptionView: View { .strokeBorder(style: StrokeStyle(lineWidth: 2, dash: [8])) .foregroundColor(Color.fluidGreen.opacity(self.isDropTargeted ? 0.7 : 0.3)) ) - .onDrop(of: [.fileURL], isTargeted: self.$isDropTargeted) { providers in - self.handleDrop(providers: providers) - } } } .fileImporter( isPresented: self.$showingFilePicker, allowedContentTypes: MeetingTranscriptionService.allowedContentTypes, - allowsMultipleSelection: false + allowsMultipleSelection: true ) { result in switch result { case let .success(urls): - if let url = urls.first { - self.selectedFileURL = url - self.transcriptionService.reset() - } + self.handleIncomingFiles(urls.map { (url: $0, stagingDir: nil) }) case let .failure(error): DebugLogger.shared.error("File picker error: \(error)", source: "MeetingTranscriptionView") } @@ -535,34 +550,187 @@ struct MeetingTranscriptionView: View { ) } - // MARK: - Helper Functions + // MARK: - Batch Transcription Section + + @ViewBuilder + private var batchSection: some View { + if let coordinator = self.batchHolder.coordinator, !coordinator.items.isEmpty { + VStack(alignment: .leading, spacing: 12) { + HStack { + Text(self.batchHeader(coordinator: coordinator)) + .font(.headline) + + Spacer() + + if coordinator.isRunning { + // Pending items stop immediately; the in-flight file may + // run to completion (native provider transcription has + // no interruption point), hence the "Cancelling" state. + if coordinator.isCancelRequested { + Text("Cancelling…") + .font(.caption) + .foregroundColor(.secondary) + } else { + Button("Cancel") { coordinator.cancel() } + .buttonStyle(.borderless) + .foregroundColor(.red) + } + } else { + Button("Done") { self.dismissBatch() } + .buttonStyle(.borderless) + } + } + + Divider() - private static let supportedFileExtensions = MeetingTranscriptionService.supportedFileExtensions - - private static let dropErrorCopy = MeetingTranscriptionService.dropErrorCopy - - private func handleDrop(providers: [NSItemProvider]) -> Bool { - guard let provider = providers.first else { return false } - provider.loadItem(forTypeIdentifier: UTType.fileURL.identifier, options: nil) { item, _ in - let url: URL? = (item as? URL) ?? (item as? Data).flatMap { URL(dataRepresentation: $0, relativeTo: nil) } - guard let url = url else { return } - let ext = url.pathExtension.lowercased() - guard Self.supportedFileExtensions.contains(ext) else { - DispatchQueue.main.async { - self.dropErrorMessage = Self.dropErrorCopy - DispatchQueue.main.asyncAfter(deadline: .now() + 3) { - self.dropErrorMessage = nil + VStack(spacing: 8) { + ForEach(coordinator.items) { item in + self.batchRow(item: item) } } - return } - DispatchQueue.main.async { - self.selectedFileURL = url - self.transcriptionService.reset() - self.dropErrorMessage = nil + .padding() + .background( + RoundedRectangle(cornerRadius: 12, style: .continuous) + .fill(self.theme.palette.cardBackground) + .overlay( + RoundedRectangle(cornerRadius: 12, style: .continuous) + .stroke(self.theme.palette.cardBorder.opacity(0.45), lineWidth: 1) + ) + ) + } + } + + private func batchHeader(coordinator: BatchTranscriptionCoordinator) -> String { + if coordinator.isRunning { + return "Transcribing \(self.currentBatchPosition(in: coordinator)) of \(coordinator.items.count)" + } + return "Batch complete — \(coordinator.completedCount) transcribed, \(coordinator.failedCount) failed" + } + + /// One-based position of the item currently being transcribed (or the next pending + /// item while between files), for the "Transcribing x of y" header. + private func currentBatchPosition(in coordinator: BatchTranscriptionCoordinator) -> Int { + let items = coordinator.items + if let index = items.firstIndex(where: { if case .transcribing = $0.status { return true }; return false }) { + return index + 1 + } + if let index = items.firstIndex(where: { if case .pending = $0.status { return true }; return false }) { + return index + 1 + } + return items.count + } + + private func batchRow(item: BatchTranscriptionCoordinator.Item) -> some View { + HStack(alignment: .top, spacing: 12) { + VStack(alignment: .leading, spacing: 2) { + Text(item.url.lastPathComponent) + .font(.system(size: 14, weight: .medium)) + .lineLimit(1) + .truncationMode(.middle) + + self.batchDetailText(for: item.status) } + + Spacer() + + self.batchStatusIcon(for: item.status) + } + .padding(12) + .background( + RoundedRectangle(cornerRadius: 8, style: .continuous) + .fill(self.theme.palette.contentBackground) + .overlay( + RoundedRectangle(cornerRadius: 8, style: .continuous) + .stroke(self.theme.palette.cardBorder.opacity(0.3), lineWidth: 1) + ) + ) + } + + @ViewBuilder + private func batchDetailText(for status: BatchTranscriptionCoordinator.Status) -> some View { + switch status { + case .failed(let message): + Text(message) + .font(.caption) + .foregroundColor(.red) + .lineLimit(2) + .truncationMode(.tail) + case .noSpeech: + Text("No speech detected") + .font(.caption) + .foregroundColor(.secondary) + case .cancelled: + Text("Cancelled") + .font(.caption) + .foregroundColor(.secondary) + default: + EmptyView() } - return true + } + + @ViewBuilder + private func batchStatusIcon(for status: BatchTranscriptionCoordinator.Status) -> some View { + switch status { + case .pending: + Image(systemName: "clock") + .foregroundColor(.secondary) + .opacity(0.5) + case .transcribing: + ProgressView() + .controlSize(.small) + .fixedSize() + case .completed: + Image(systemName: "checkmark.circle.fill") + .foregroundColor(Color.fluidGreen) + case .noSpeech: + Image(systemName: "speaker.slash.fill") + .foregroundColor(.secondary) + case .failed: + Image(systemName: "exclamationmark.triangle.fill") + .foregroundColor(.red) + case .cancelled: + Image(systemName: "xmark.circle.fill") + .foregroundColor(.secondary) + } + } + + // MARK: - Helper Functions + + /// True while a batch coordinator exists with any enqueued items (running or + /// finished-but-not-dismissed). Used to suppress the single-file cards while a + /// batch is in progress, since `transcribeFile` mutates the shared service state + /// for each batch item. + private var isBatchActive: Bool { + guard let coordinator = self.batchHolder.coordinator else { return false } + return !coordinator.items.isEmpty + } + + /// Routes incoming files from a drop or the file picker. + /// + /// A single concrete file (no staging directory) follows the existing single-file + /// flow: select it and wait for the user to tap Transcribe. Everything else — two + /// or more files, or any staged (promised) file — is enqueued on the batch + /// coordinator so staged directories are reliably cleaned up after transcription. + private func handleIncomingFiles(_ files: [(url: URL, stagingDir: URL?)]) { + guard !files.isEmpty else { return } + self.dropErrorMessage = nil + + let batchIsRunning = self.batchHolder.coordinator?.isRunning == true + if files.count == 1, let file = files.first, file.stagingDir == nil, !batchIsRunning { + self.selectedFileURL = file.url + self.transcriptionService.reset() + return + } + + self.batchHolder.enqueue(files.map { .init(url: $0.url, stagingDir: $0.stagingDir) }) + } + + /// Clears the batch list and resets shared service state so a subsequent batch + /// starts fresh and no stale single-file result lingers. + private func dismissBatch() { + self.batchHolder.clear() + self.transcriptionService.reset() } private func transcribeFile() async { @@ -603,6 +771,8 @@ struct MeetingTranscriptionView: View { } } +// MARK: - Batch Coordinator Ownership + // MARK: - Document for Export struct TranscriptionDocument: FileDocument { diff --git a/Sources/Fluid/UI/PromiseAwareDropView.swift b/Sources/Fluid/UI/PromiseAwareDropView.swift new file mode 100644 index 00000000..16eec755 --- /dev/null +++ b/Sources/Fluid/UI/PromiseAwareDropView.swift @@ -0,0 +1,544 @@ +import AppKit +import SwiftUI + +/// A drop target that accepts both concrete file URLs and file-promise drags +/// (e.g. from Voice Memos), and resolves promised files into per-item staging +/// directories before reporting them via callbacks. +/// +/// The pure strategy/staging/filtering logic lives in `PromiseDropSupport`; +/// this view only owns AppKit drag plumbing and the async resolution poll. +struct PromiseAwareDropView: NSViewRepresentable { + let onTargetedChange: (Bool) -> Void + let onFiles: ([(url: URL, stagingDir: URL?)]) -> Void + let onError: (String) -> Void + + func makeNSView(context: Context) -> DropTargetView { + let view = DropTargetView() + view.onTargetedChange = self.onTargetedChange + view.onFiles = self.onFiles + view.onError = self.onError + return view + } + + func updateNSView(_ nsView: DropTargetView, context: Context) { + nsView.onTargetedChange = self.onTargetedChange + nsView.onFiles = self.onFiles + nsView.onError = self.onError + } + + // MARK: - Drop target + + final class DropTargetView: NSView { + var onTargetedChange: (Bool) -> Void = { _ in } + var onFiles: ([(url: URL, stagingDir: URL?)]) -> Void = { _ in } + var onError: (String) -> Void = { _ in } + + /// Shared background queue for `NSFilePromiseReceiver` resolution. Static + /// so in-flight promise resolution survives the view being destroyed + /// (e.g. by sidebar navigation) mid-drop. + private static let promiseQueue: OperationQueue = { + let queue = OperationQueue() + queue.maxConcurrentOperationCount = 4 + return queue + }() + + override init(frame frameRect: NSRect) { + super.init(frame: frameRect) + self.configureDropTypes() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + self.configureDropTypes() + } + + private func configureDropTypes() { + let promiseTypes = NSFilePromiseReceiver.readableDraggedTypes.map { NSPasteboard.PasteboardType(rawValue: $0) } + self.registerForDraggedTypes([.fileURL] + promiseTypes) + } + + /// The view sits in an `.overlay` so AppKit's front-to-back drag-target + /// search finds it above the SwiftUI content; returning nil here lets + /// every normal mouse event fall through to the UI beneath. Drag + /// dispatch does not consult `hitTest`, so drops still arrive. + override func hitTest(_ point: NSPoint) -> NSView? { + nil + } + + override func viewDidMoveToWindow() { + super.viewDidMoveToWindow() + DebugLogger.shared.debug( + "Drop target attached [inWindow=\(self.window != nil), frame=\(self.frame)]", + source: "PromiseAwareDropView" + ) + } + + override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation { + let types = (sender.draggingPasteboard.types ?? []).map(\.rawValue) + let strategy = PromiseDropSupport.strategy(forPasteboardTypes: types) + DebugLogger.shared.debug( + "Drag entered [strategy=\(String(describing: strategy)), frame=\(self.frame)]", + source: "PromiseAwareDropView" + ) + guard strategy != nil else { + return [] + } + self.onTargetedChange(true) + return .copy + } + + override func draggingExited(_ sender: NSDraggingInfo?) { + self.onTargetedChange(false) + } + + override func draggingEnded(_ sender: NSDraggingInfo) { + self.onTargetedChange(false) + } + + override func performDragOperation(_ sender: NSDraggingInfo) -> Bool { + let pasteboard = sender.draggingPasteboard + let types = (pasteboard.types ?? []).map(\.rawValue) + DebugLogger.shared.debug( + "Perform drag [types=\(types.count)]", + source: "PromiseAwareDropView" + ) + guard let strategy = PromiseDropSupport.strategy(forPasteboardTypes: types) else { + self.onError(MeetingTranscriptionService.dropErrorCopy) + return false + } + + switch strategy { + case .concreteFileURLs: + return self.handleConcreteURLs(pasteboard: pasteboard) + case .filePromise: + return self.handleFilePromises(sender: sender, pasteboard: pasteboard) + } + } + + // MARK: - Concrete File URLs + + private func handleConcreteURLs(pasteboard: NSPasteboard) -> Bool { + let options: [NSPasteboard.ReadingOptionKey: Any] = [.urlReadingFileURLsOnly: true] + guard let urls = pasteboard.readObjects(forClasses: [NSURL.self], options: options) as? [URL], + !urls.isEmpty else { + self.onError(MeetingTranscriptionService.dropErrorCopy) + return false + } + + let supported = PromiseDropSupport.filterSupported(urls) + if supported.isEmpty { + self.onError(MeetingTranscriptionService.dropErrorCopy) + return false + } + + self.onFiles(supported.map { (url: $0, stagingDir: nil) }) + return true + } + + // MARK: - File Promises + + private func handleFilePromises(sender: NSDraggingInfo, pasteboard: NSPasteboard) -> Bool { + let session: PromiseDropSupport.StagingSession + do { + session = try PromiseDropSupport.StagingSession() + } catch { + self.onError("Could not prepare a staging directory for the drop: \(error.localizedDescription)") + return false + } + let legacyDir = try? session.makeItemDirectory() + let dataDir = try? session.makeItemDirectory() + // Captured by value so resolution keeps working (and can still hand + // files to the app-level batch session) if this view is destroyed + // by navigation while the drop is resolving. + let onFiles = self.onFiles + let onError = self.onError + + // Every pasteboard read can block indefinitely (verified: the same + // read is instant on one drop and deadlocks on the next), and a + // block inside performDragOperation freezes the system-wide drag + // session. So performDragOperation returns immediately and ALL + // pasteboard interaction happens on throwaway background threads; + // the main thread only ever polls the staging directories. + // + // NOTE: using `sender`/`pasteboard` after performDragOperation has + // returned, from another thread, is outside AppKit's documented + // lifetime contract. It is the only arrangement that neither + // deadlocks nor loses the drop (verified live against Voice Memos); + // if a provider stops answering, the reads fail harmlessly on their + // background threads and the poll timeout reports the failure. + let state = ResolutionState() + state.beginInFlight() // outer worker token, released when it finishes + + // The poller starts before any pasteboard read, so even a worker + // thread that hangs on its first read cannot leave the drop without + // a timeout/error path. Deliberately not tied to the view lifetime. + Task { @MainActor in + await DropTargetView.resolvePromises( + session: session, + state: state, + legacyDir: legacyDir, + dataDir: dataDir, + onFiles: onFiles, + onError: onError + ) + } + + Self.detachWorker { + defer { state.endInFlight() } + + // Modern path: each NSFilePromiseReceiver writes into its own + // item directory via the shared background operation queue. A + // directory counts as delivered only after its completion + // callback fires — polling alone could hand over a file whose + // (e.g. iCloud) download stalled mid-write. + if let receivers = pasteboard.readObjects(forClasses: [NSFilePromiseReceiver.self], options: nil) as? [NSFilePromiseReceiver] { + for receiver in receivers { + guard let dir = try? session.makeItemDirectory() else { continue } + state.registerReceiverDir(dir) + receiver.receivePromisedFiles(atDestination: dir, options: [:], operationQueue: Self.promiseQueue) { url, error in + if let error { + DebugLogger.shared.debug( + "Modern promise receiver failed [\(url.lastPathComponent)]: \(error.localizedDescription)", + source: "PromiseAwareDropView" + ) + } else { + state.markCompleted(dir) + } + } + } + } + + let suggestedName = pasteboard.string( + forType: NSPasteboard.PasteboardType("com.apple.pasteboard.promised-suggested-file-name") + ) + let promisedTypeID = pasteboard.string( + forType: NSPasteboard.PasteboardType("com.apple.pasteboard.promised-file-content-type") + ) + DebugLogger.shared.debug( + "Promise drop [receivers=\(state.receiverDirsSnapshot().count), type=\(promisedTypeID ?? "?"), name=\(suggestedName ?? "?")]", + source: "PromiseAwareDropView" + ) + + // Raw-data fallback: some providers (verified for Voice Memos) + // also put the complete file bytes on the pasteboard under the + // promised content type. Memory-heavy for long recordings, so + // it is the last resort in the delivery priority order. + if let dataDir, let typeID = promisedTypeID { + let fileName = suggestedName ?? "Dropped Audio" + guard let data = pasteboard.data(forType: NSPasteboard.PasteboardType(typeID)), + !data.isEmpty else { return } + let target = dataDir.appendingPathComponent(fileName) + do { + try data.write(to: target) + DebugLogger.shared.debug( + "Raw-data fallback wrote \(data.count) bytes to \(target.lastPathComponent)", + source: "PromiseAwareDropView" + ) + } catch { + DebugLogger.shared.debug( + "Raw-data fallback write failed: \(error.localizedDescription)", + source: "PromiseAwareDropView" + ) + } + } + + // Legacy fallback (deprecated namesOfPromisedFilesDroppedAtDestination:), + // strictly last resort. A pending legacy request freezes the + // source app's promise machinery until it answers (verified + // live: Voice Memos unresponsive for 35-80s, blocking further + // drags), so it only fires if neither the modern receiver nor + // the raw-data path has produced anything within a short + // window. Invoked via perform(_:) with a string selector so no + // deprecation warning is emitted. + if let legacyDir { + let waitDeadline = Date().addingTimeInterval(3) + var otherPathDelivered = false + while Date() < waitDeadline { + let dataLanded = dataDir.map { + !((try? FileManager.default.contentsOfDirectory(atPath: $0.path)) ?? []).isEmpty + } ?? false + if dataLanded || !state.completedSnapshot().isEmpty { + otherPathDelivered = true + break + } + Thread.sleep(forTimeInterval: 0.2) + } + if !otherPathDelivered { + state.beginInFlight() + Self.detachWorker { + defer { state.endInFlight() } + let selector = Selector(("namesOfPromisedFilesDroppedAtDestination:")) + let names = (sender.perform(selector, with: legacyDir)? + .takeUnretainedValue() as? [String]) ?? [] + DebugLogger.shared.debug( + "Legacy promise names: \(names)", + source: "PromiseAwareDropView" + ) + } + } + } + } + return true + } + + /// Thread-safe resolution state shared between the background delivery + /// threads and the main-actor poller: which receiver dirs have completed, + /// and whether the legacy/raw-data reads are still in flight (under heavy + /// inference load a provider can take 60s+ to answer — verified live — + /// and the poller must not give up and sweep the staging dirs while an + /// answer is still coming). + private final class ResolutionState: @unchecked Sendable { + private let lock = NSLock() + private var receiverDirs: [URL] = [] + private var completed: Set = [] + private var inFlightCount = 0 + + func registerReceiverDir(_ dir: URL) { + self.lock.lock() + defer { self.lock.unlock() } + self.receiverDirs.append(dir) + } + + func receiverDirsSnapshot() -> [URL] { + self.lock.lock() + defer { self.lock.unlock() } + return self.receiverDirs + } + + func markCompleted(_ dir: URL) { + self.lock.lock() + defer { self.lock.unlock() } + self.completed.insert(dir) + } + + func completedSnapshot() -> Set { + self.lock.lock() + defer { self.lock.unlock() } + return self.completed + } + + func beginInFlight() { + self.lock.lock() + defer { self.lock.unlock() } + self.inFlightCount += 1 + } + + func endInFlight() { + self.lock.lock() + defer { self.lock.unlock() } + self.inFlightCount -= 1 + } + + var hasInFlightWork: Bool { + self.lock.lock() + defer { self.lock.unlock() } + return self.inFlightCount > 0 + } + } + + /// Detached worker at user-initiated QoS: default-QoS threads get starved + /// while ML inference saturates the cores, which is exactly when a second + /// drop arrives mid-batch. + private static func detachWorker(_ body: @escaping () -> Void) { + let thread = Thread(block: body) + thread.qualityOfService = .userInitiated + thread.start() + } + + // MARK: - Promise Resolution Poll + + private static func resolvePromises( + session: PromiseDropSupport.StagingSession, + state: ResolutionState, + legacyDir: URL?, + dataDir: URL?, + onFiles: @escaping ([(url: URL, stagingDir: URL?)]) -> Void, + onError: @escaping (String) -> Void + ) async { + let pollInterval: UInt64 = 200_000_000 + let softTimeout: TimeInterval = 30 + // Under heavy inference load a provider can take 60s+ to answer + // (verified live: 80s for a second drop mid-batch). While any + // delivery thread is still in flight the poll keeps waiting, up to + // a hard cap so a truly wedged provider still ends in an error. + let hardTimeout: TimeInterval = 120 + let modernGrace: TimeInterval = 1.5 + let start = Date() + + func makeContext() -> DeliveryContext { + let receiverDirs = state.receiverDirsSnapshot() + let completed = state.completedSnapshot() + return DeliveryContext( + allDirs: receiverDirs + [legacyDir, dataDir].compactMap(\.self), + pendingReceiverDirs: receiverDirs.filter { !completed.contains($0) }, + totalExpected: max(receiverDirs.count, 1), + session: session, + onFiles: onFiles, + onError: onError + ) + } + + var fallbackPrevSizes: [URL: Int64] = [:] + + while true { + let elapsed = Date().timeIntervalSince(start) + if elapsed >= hardTimeout { break } + if elapsed >= softTimeout, !state.hasInFlightWork { break } + + // A receiver dir only counts once its completion callback fired — + // a stalled (e.g. iCloud) download must never be delivered as a + // truncated file just because its size held still between polls. + let receiverDirs = state.receiverDirsSnapshot() + let readyModernDirs = state.completedSnapshot() + let modernFiles = self.listFiles(in: receiverDirs.filter(readyModernDirs.contains)) + let legacyFiles = self.listFiles(in: [legacyDir].compactMap(\.self)) + let dataFiles = self.listFiles(in: [dataDir].compactMap(\.self)) + let fallbackSizes = self.sizeMap(for: legacyFiles + dataFiles) + + // Modern succeeded outright: every registered receiver completed. + // (Receivers register in one tight loop with no pasteboard call + // in between, so a partially-registered snapshot is a micro-race + // at worst; completion still requires each dir's callback.) + let modernComplete = !receiverDirs.isEmpty + && readyModernDirs.count >= receiverDirs.count + && !modernFiles.isEmpty + if modernComplete { + self.deliver(modern: modernFiles, legacy: legacyFiles, data: dataFiles, context: makeContext()) + return + } + + // Modern produced nothing past the grace period but a fallback + // landed and its sizes are stable — use the fallback copies. + let modernProducedNothing = readyModernDirs.isEmpty && elapsed > modernGrace + let fallbackStable = !fallbackSizes.isEmpty && fallbackSizes == fallbackPrevSizes + if modernProducedNothing && fallbackStable { + self.deliver(modern: [], legacy: legacyFiles, data: dataFiles, context: makeContext()) + return + } + + fallbackPrevSizes = fallbackSizes + try? await Task.sleep(nanoseconds: pollInterval) + } + + // Timeout: deliver whatever completed, preferring modern. Incomplete + // receiver dirs are excluded (possible truncation) and surface via + // the partial-failure error below. + let receiverDirs = state.receiverDirsSnapshot() + let readyModernDirs = state.completedSnapshot() + self.deliver( + modern: self.listFiles(in: receiverDirs.filter(readyModernDirs.contains)), + legacy: self.listFiles(in: [legacyDir].compactMap(\.self)), + data: self.listFiles(in: [dataDir].compactMap(\.self)), + context: makeContext() + ) + } + + /// Everything `deliver` needs besides the per-path file lists. + private struct DeliveryContext { + let allDirs: [URL] + /// Receiver dirs whose promise hasn't completed yet. They must NOT + /// be swept at delivery: the source app may still be writing into + /// them, and deleting the destination leaves its promise session + /// unresolved — Voice Memos then refuses to start any further drag + /// until restarted (verified live). They're cleaned up after the + /// promise completes (or a 120s deadline) by a deferred task. + let pendingReceiverDirs: [URL] + let totalExpected: Int + let session: PromiseDropSupport.StagingSession + let onFiles: ([(url: URL, stagingDir: URL?)]) -> Void + let onError: (String) -> Void + } + + /// Delivers the resolved files. Selection/dedup rules live in + /// `PromiseDropSupport.selectDelivery`; unsupported formats are filtered + /// like the concrete-URL path. + private static func deliver( + modern: [URL], + legacy: [URL], + data: [URL], + context: DeliveryContext + ) { + DebugLogger.shared.debug( + "Promise delivery [modern=\(modern.count), legacy=\(legacy.count), data=\(data.count), expected=\(context.totalExpected)]", + source: "PromiseAwareDropView" + ) + let selected = PromiseDropSupport.selectDelivery(modern: modern, legacy: legacy, data: data) + let supported = PromiseDropSupport.filterSupported(selected) + let result = supported.map { (url: $0, stagingDir: $0.deletingLastPathComponent()) } + + if result.isEmpty { + context.session.removeAll() + let reason = selected.isEmpty + ? "No files could be read from the drop." + : "The dropped files are not a supported format." + context.onError("\(reason) \(MeetingTranscriptionService.dropErrorCopy)") + return + } + + // Item dirs that hold no delivered file — losing duplicates (e.g. the + // raw-data copy when the modern receiver won) and empty shells from + // failed paths — are dead weight. Deleting them can race the still- + // running legacy/data writer threads; that is harmless (the losers' + // files are throwaway copies) and keeps the temp dir clean. The + // batch coordinator removes the delivered dirs (and then the empty + // session root) after each item's transcription. + let pendingPaths = Set(context.pendingReceiverDirs.map(\.standardizedFileURL.path)) + for dir in PromiseDropSupport.sweepableDirs(allDirs: context.allDirs, deliveredFiles: supported) + where !pendingPaths.contains(dir.standardizedFileURL.path) { + try? FileManager.default.removeItem(at: dir) + } + + context.onFiles(result) + if result.count < context.totalExpected { + context.onError("\(context.totalExpected - result.count) file(s) could not be read from the drop.") + } + + self.cleanUpLater(pendingDirs: context.pendingReceiverDirs) + } + + /// Removes still-pending receiver dirs once their promise has had time + /// to finish writing (their content is a duplicate of what was already + /// delivered), then prunes the session root if it ended up empty. + private static func cleanUpLater(pendingDirs: [URL]) { + guard !pendingDirs.isEmpty else { return } + Task { @MainActor in + try? await Task.sleep(nanoseconds: 120_000_000_000) + for dir in pendingDirs { + try? FileManager.default.removeItem(at: dir) + } + for parent in Set(pendingDirs.map { $0.deletingLastPathComponent() }) + where parent.lastPathComponent.hasPrefix(PromiseDropSupport.stagingRootPrefix) { + if ((try? FileManager.default.contentsOfDirectory(atPath: parent.path)) ?? []).isEmpty { + try? FileManager.default.removeItem(at: parent) + } + } + } + } + + // MARK: - Filesystem Helpers + + private static func listFiles(in dirs: [URL]) -> [URL] { + var files: [URL] = [] + for dir in dirs { + guard let entries = try? FileManager.default.contentsOfDirectory( + at: dir, + includingPropertiesForKeys: [.fileSizeKey], + options: [.skipsHiddenFiles] + ) else { continue } + for entry in entries where !entry.hasDirectoryPath { + files.append(entry) + } + } + return files + } + + private static func sizeMap(for urls: [URL]) -> [URL: Int64] { + var map: [URL: Int64] = [:] + for url in urls { + let size = (try? url.resourceValues(forKeys: [.fileSizeKey]).fileSize) ?? 0 + map[url] = Int64(size) + } + return map + } + } +} diff --git a/Sources/Fluid/UI/PromiseDropSupport.swift b/Sources/Fluid/UI/PromiseDropSupport.swift new file mode 100644 index 00000000..9fdc80e7 --- /dev/null +++ b/Sources/Fluid/UI/PromiseDropSupport.swift @@ -0,0 +1,139 @@ +import AVFoundation +import Foundation +import UniformTypeIdentifiers + +/// Testable, nonisolated core logic for the promise-aware drop path (issue #219). +/// +/// The AppKit drop view (`PromiseAwareDropView`) needs a live drag session, so it +/// delegates the pure pieces here: deciding whether a pasteboard carries concrete +/// file URLs or file promises, staging promised files into collision-free per-item +/// directories, and filtering drops to formats AVFoundation can actually decode. +/// Everything is `nonisolated` so it can be unit-tested from a nonisolated test +/// context despite the app target's `MainActor` default actor isolation. +nonisolated enum PromiseDropSupport { + /// How a given pasteboard should be interpreted. + enum Strategy: Equatable { + /// Concrete file URLs are present (`public.file-url`). + case concreteFileURLs + /// Only file-promise metadata is present (e.g. a Voice Memos drag). + case filePromise + } + + /// The pasteboard type that carries a concrete file URL. + private static let concreteFileURLType = "public.file-url" + + /// Pasteboard type identifiers that signal a file-promise drop. Voice Memos + /// emits a mix of these (verified live 2026-07-25); any one is sufficient. + private static let filePromiseTypes: Set = [ + "com.apple.NSFilePromiseItemMetaData", + "com.apple.pasteboard.promised-file-content-type", + "Apple files promise pasteboard type", + ] + + /// Decides the drop strategy from raw pasteboard type strings. + /// + /// Concrete file URLs win over promises when both are present. Promises are + /// only accepted when the pasteboard also advertises an audio/movie content + /// type (Voice Memos exposes e.g. `com.apple.m4a-audio` directly in the + /// type list) — so an image promise from Photos is rejected up front rather + /// than staged and failed later. Returns `nil` for pasteboards that carry + /// neither file URLs nor decodable promises. + static func strategy(forPasteboardTypes types: [String]) -> Strategy? { + if types.contains(concreteFileURLType) { + return .concreteFileURLs + } + guard types.contains(where: { filePromiseTypes.contains($0) }) else { + return nil + } + let promisesAudioVisualContent = types.contains { type in + guard let utType = UTType(type) else { return false } + return utType.conforms(to: .audio) || utType.conforms(to: .movie) + } + return promisesAudioVisualContent ? .filePromise : nil + } + + /// Staging dirs that hold no delivered file and should be swept. + /// + /// Compares standardized *paths*, not URLs: a directory built via + /// `appendingPathComponent` and the same directory derived from a file via + /// `deletingLastPathComponent()` differ in trailing-slash form and compare + /// unequal as URLs — which once made the sweep delete a delivered file. + static func sweepableDirs(allDirs: [URL], deliveredFiles: [URL]) -> [URL] { + let deliveredDirPaths = Set(deliveredFiles.map { + $0.deletingLastPathComponent().standardizedFileURL.path + }) + return allDirs.filter { !deliveredDirPaths.contains($0.standardizedFileURL.path) } + } + + /// Merges the three promise-delivery paths into the final file list. + /// + /// Every modern-receiver file is delivered: each receiver stages into its own + /// directory, so two distinct memos that share a display name (e.g. two + /// "New Recording.m4a") are distinct files and must never be collapsed. + /// Legacy and raw-data files are alternates of the same dragged items, so + /// they only contribute names the delivered set doesn't already contain. + static func selectDelivery(modern: [URL], legacy: [URL], data: [URL]) -> [URL] { + var delivered = modern + var names = Set(modern.map(\.lastPathComponent)) + for url in legacy + data where !names.contains(url.lastPathComponent) { + delivered.append(url) + names.insert(url.lastPathComponent) + } + return delivered + } + + /// Audio/movie file extensions the OS can decode, queried nonisolated from + /// AVFoundation. Mirrors `MeetingTranscriptionService.supportedFileExtensions` + /// but is safe to call from any isolation context. + private static let supportedExtensions: Set = { + let avTypes = AVURLAsset.audiovisualTypes() + let extensions = avTypes.compactMap { fileType -> String? in + guard let utType = UTType(fileType.rawValue) else { return nil } + guard utType.conforms(to: .audio) || utType.conforms(to: .movie) else { return nil } + return utType.preferredFilenameExtension?.lowercased() + } + return Set(extensions) + }() + + /// Keeps only URLs whose (lowercased) extension is a decodable audio/movie + /// format. Order-preserving. + static func filterSupported(_ urls: [URL]) -> [URL] { + return urls.filter { url in + let ext = url.pathExtension.lowercased() + return !ext.isEmpty && supportedExtensions.contains(ext) + } + } + + /// A scratch directory tree under the user temp dir that gives each promised + /// file its own subdirectory, so identically-named files (e.g. several Voice + /// Memos drops named "New Recording.m4a") never collide. + /// + /// All state is immutable, so the session is `Sendable` and safe to share + /// across the main actor and the background queue that resolves promises. + /// Prefix of every drop-session staging root; the batch coordinator uses it + /// to recognize (and prune) empty session roots after item cleanup. + static let stagingRootPrefix = "PromiseDrop-" + + final class StagingSession: Sendable { + private let root: URL + + /// Creates a unique root directory under the user temp dir. + init() throws { + self.root = FileManager.default.temporaryDirectory + .appendingPathComponent("\(PromiseDropSupport.stagingRootPrefix)\(UUID().uuidString)") + try FileManager.default.createDirectory(at: self.root, withIntermediateDirectories: true) + } + + /// Creates a fresh, unique subdirectory for a single promised item. + func makeItemDirectory() throws -> URL { + let dir = self.root.appendingPathComponent("item-\(UUID().uuidString)") + try FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true) + return dir + } + + /// Deletes the whole staging tree. + func removeAll() { + try? FileManager.default.removeItem(at: self.root) + } + } +} diff --git a/Tests/FluidDictationIntegrationTests/BatchTranscriptionCoordinatorTests.swift b/Tests/FluidDictationIntegrationTests/BatchTranscriptionCoordinatorTests.swift new file mode 100644 index 00000000..c8ddf44f --- /dev/null +++ b/Tests/FluidDictationIntegrationTests/BatchTranscriptionCoordinatorTests.swift @@ -0,0 +1,384 @@ +@testable import FluidVoice_Debug +import Foundation +import XCTest + +/// Contract tests for BatchTranscriptionCoordinator (issue #219 batch transcription). +/// The coordinator owns per-item state for multi-file transcription: sequential +/// processing, per-item success/failure, cancellation, staging-dir cleanup, and +/// batch start/end hooks for dictation arbitration. +@MainActor +final class BatchTranscriptionCoordinatorTests: XCTestCase { + private func makeResult(text: String, fileName: String = "test.m4a") -> TranscriptionResult { + TranscriptionResult( + text: text, + confidence: 0.9, + duration: 1.0, + processingTime: 0.1, + fileName: fileName + ) + } + + private func tempAudioURL(name: String) -> URL { + FileManager.default.temporaryDirectory + .appendingPathComponent("batch-tests-\(UUID().uuidString)", isDirectory: true) + .appendingPathComponent(name) + } + + // MARK: - Sequential processing & ordering + + func testProcessesFilesSequentiallyInOrder() async { + var transcribedPaths: [String] = [] + var concurrent = 0 + var maxConcurrent = 0 + + let coordinator = BatchTranscriptionCoordinator(transcribe: { url in + concurrent += 1 + maxConcurrent = max(maxConcurrent, concurrent) + try? await Task.sleep(nanoseconds: 20_000_000) + transcribedPaths.append(url.lastPathComponent) + concurrent -= 1 + return self.makeResult(text: "text for \(url.lastPathComponent)", fileName: url.lastPathComponent) + }) + + let urls = ["a.m4a", "b.m4a", "c.m4a"].map { self.tempAudioURL(name: $0) } + coordinator.enqueue(urls.map { BatchTranscriptionCoordinator.Request(url: $0) }) + await coordinator.waitUntilIdle() + + XCTAssertEqual(transcribedPaths, ["a.m4a", "b.m4a", "c.m4a"], "files must process in enqueue order") + XCTAssertEqual(maxConcurrent, 1, "batch must never transcribe two files concurrently") + XCTAssertFalse(coordinator.isRunning) + XCTAssertEqual(coordinator.items.count, 3) + for item in coordinator.items { + guard case let .completed(result) = item.status else { + return XCTFail("expected .completed, got \(item.status)") + } + XCTAssertEqual(result.text, "text for \(item.url.lastPathComponent)") + } + } + + func testIsRunningTrueWhileProcessing() async { + let gate = AsyncGate() + let coordinator = BatchTranscriptionCoordinator(transcribe: { url in + await gate.wait() + return self.makeResult(text: "done", fileName: url.lastPathComponent) + }) + + coordinator.enqueue([.init(url: self.tempAudioURL(name: "a.m4a"))]) + // Let the processing task start. + await Task.yield() + try? await Task.sleep(nanoseconds: 50_000_000) + XCTAssertTrue(coordinator.isRunning) + if case .transcribing = coordinator.items[0].status {} else { + XCTFail("expected first item to be .transcribing, got \(coordinator.items[0].status)") + } + + gate.open() + await coordinator.waitUntilIdle() + XCTAssertFalse(coordinator.isRunning) + } + + // MARK: - Per-item failure isolation + + func testFailedItemDoesNotStopBatch() async { + let coordinator = BatchTranscriptionCoordinator(transcribe: { url in + if url.lastPathComponent == "bad.m4a" { + throw MeetingTranscriptionService.TranscriptionError.transcriptionFailed("decode blew up") + } + return self.makeResult(text: "ok", fileName: url.lastPathComponent) + }) + + coordinator.enqueue([ + .init(url: self.tempAudioURL(name: "good1.m4a")), + .init(url: self.tempAudioURL(name: "bad.m4a")), + .init(url: self.tempAudioURL(name: "good2.m4a")), + ]) + await coordinator.waitUntilIdle() + + guard case .completed = coordinator.items[0].status else { + return XCTFail("item 0 should complete, got \(coordinator.items[0].status)") + } + guard case let .failed(message) = coordinator.items[1].status else { + return XCTFail("item 1 should fail, got \(coordinator.items[1].status)") + } + XCTAssertTrue(message.contains("decode blew up"), "failure must preserve the underlying error message") + guard case .completed = coordinator.items[2].status else { + return XCTFail("item 2 should still complete after a failure, got \(coordinator.items[2].status)") + } + } + + // MARK: - Empty transcription + + func testEmptyTranscriptionMarksNoSpeech() async { + let coordinator = BatchTranscriptionCoordinator(transcribe: { url in + self.makeResult(text: " ", fileName: url.lastPathComponent) + }) + + coordinator.enqueue([.init(url: self.tempAudioURL(name: "silent.m4a"))]) + await coordinator.waitUntilIdle() + + guard case .noSpeech = coordinator.items[0].status else { + return XCTFail("whitespace-only transcription must surface as .noSpeech, got \(coordinator.items[0].status)") + } + } + + // MARK: - Cancellation + + func testCancelStopsCurrentItemAndPendingItems() async { + let started = AsyncGate() + let coordinator = BatchTranscriptionCoordinator(transcribe: { url in + started.open() + // Simulate a long transcription that honors Task cancellation. + try await Task.sleep(nanoseconds: 10_000_000_000) + return self.makeResult(text: "should never finish", fileName: url.lastPathComponent) + }) + + coordinator.enqueue([ + .init(url: self.tempAudioURL(name: "current.m4a")), + .init(url: self.tempAudioURL(name: "pending1.m4a")), + .init(url: self.tempAudioURL(name: "pending2.m4a")), + ]) + await started.wait() + coordinator.cancel() + await coordinator.waitUntilIdle() + + XCTAssertFalse(coordinator.isRunning) + guard case .cancelled = coordinator.items[0].status else { + return XCTFail("in-flight item must be .cancelled, not \(coordinator.items[0].status)") + } + guard case .cancelled = coordinator.items[1].status else { + return XCTFail("pending items must be .cancelled, not \(coordinator.items[1].status)") + } + guard case .cancelled = coordinator.items[2].status else { + return XCTFail("pending items must be .cancelled, not \(coordinator.items[2].status)") + } + } + + func testEnqueueAfterCancelStartsFreshBatch() async { + let coordinator = BatchTranscriptionCoordinator(transcribe: { url in + self.makeResult(text: "ok", fileName: url.lastPathComponent) + }) + coordinator.cancel() // cancel with nothing running must be a no-op + + coordinator.enqueue([.init(url: self.tempAudioURL(name: "after.m4a"))]) + await coordinator.waitUntilIdle() + + guard case .completed = coordinator.items.last!.status else { + return XCTFail("batch must run normally after a cancel, got \(coordinator.items.last!.status)") + } + } + + // MARK: - Staging directory cleanup + + func testStagingDirRemovedAfterItemFinishes() async throws { + let fm = FileManager.default + let stagingDir = fm.temporaryDirectory.appendingPathComponent("staging-\(UUID().uuidString)", isDirectory: true) + try fm.createDirectory(at: stagingDir, withIntermediateDirectories: true) + let audioURL = stagingDir.appendingPathComponent("memo.m4a") + try Data([0x00]).write(to: audioURL) + + var existedDuringTranscription = false + let coordinator = BatchTranscriptionCoordinator(transcribe: { url in + existedDuringTranscription = fm.fileExists(atPath: url.path) + return self.makeResult(text: "ok", fileName: url.lastPathComponent) + }) + + coordinator.enqueue([.init(url: audioURL, stagingDir: stagingDir)]) + await coordinator.waitUntilIdle() + + XCTAssertTrue(existedDuringTranscription, "staged file must exist for the whole transcription") + XCTAssertFalse(fm.fileExists(atPath: stagingDir.path), "staging dir must be deleted after the item finishes") + } + + func testStagingDirRemovedEvenWhenItemFails() async throws { + let fm = FileManager.default + let stagingDir = fm.temporaryDirectory.appendingPathComponent("staging-\(UUID().uuidString)", isDirectory: true) + try fm.createDirectory(at: stagingDir, withIntermediateDirectories: true) + let audioURL = stagingDir.appendingPathComponent("memo.m4a") + try Data([0x00]).write(to: audioURL) + + let coordinator = BatchTranscriptionCoordinator(transcribe: { _ in + throw MeetingTranscriptionService.TranscriptionError.transcriptionFailed("nope") + }) + + coordinator.enqueue([.init(url: audioURL, stagingDir: stagingDir)]) + await coordinator.waitUntilIdle() + + XCTAssertFalse(fm.fileExists(atPath: stagingDir.path), "staging dir must be deleted even on failure") + } + + func testEmptySessionRootPrunedAfterLastItemCleanup() async throws { + let fm = FileManager.default + let sessionRoot = fm.temporaryDirectory.appendingPathComponent("PromiseDrop-\(UUID().uuidString)", isDirectory: true) + let stagingDir = sessionRoot.appendingPathComponent("item-\(UUID().uuidString)", isDirectory: true) + try fm.createDirectory(at: stagingDir, withIntermediateDirectories: true) + let audioURL = stagingDir.appendingPathComponent("memo.m4a") + try Data([0x00]).write(to: audioURL) + + let coordinator = BatchTranscriptionCoordinator(transcribe: { url in + self.makeResult(text: "ok", fileName: url.lastPathComponent) + }) + + coordinator.enqueue([.init(url: audioURL, stagingDir: stagingDir)]) + await coordinator.waitUntilIdle() + + XCTAssertFalse( + fm.fileExists(atPath: sessionRoot.path), + "an empty PromiseDrop- session root must be pruned once its last item dir is cleaned" + ) + } + + func testNonPromiseParentDirectoryIsNotPruned() async throws { + let fm = FileManager.default + let parent = fm.temporaryDirectory.appendingPathComponent("user-folder-\(UUID().uuidString)", isDirectory: true) + let stagingDir = parent.appendingPathComponent("item-\(UUID().uuidString)", isDirectory: true) + try fm.createDirectory(at: stagingDir, withIntermediateDirectories: true) + let audioURL = stagingDir.appendingPathComponent("memo.m4a") + try Data([0x00]).write(to: audioURL) + defer { try? fm.removeItem(at: parent) } + + let coordinator = BatchTranscriptionCoordinator(transcribe: { url in + self.makeResult(text: "ok", fileName: url.lastPathComponent) + }) + + coordinator.enqueue([.init(url: audioURL, stagingDir: stagingDir)]) + await coordinator.waitUntilIdle() + + XCTAssertTrue( + fm.fileExists(atPath: parent.path), + "only PromiseDrop- session roots may be pruned; other parent dirs must be left alone" + ) + } + + func testNonStagedFileIsNeverDeleted() async throws { + let fm = FileManager.default + let dir = fm.temporaryDirectory.appendingPathComponent("user-files-\(UUID().uuidString)", isDirectory: true) + try fm.createDirectory(at: dir, withIntermediateDirectories: true) + let audioURL = dir.appendingPathComponent("user-owned.m4a") + try Data([0x00]).write(to: audioURL) + defer { try? fm.removeItem(at: dir) } + + let coordinator = BatchTranscriptionCoordinator(transcribe: { url in + self.makeResult(text: "ok", fileName: url.lastPathComponent) + }) + + coordinator.enqueue([.init(url: audioURL)]) // no stagingDir: user's own file + await coordinator.waitUntilIdle() + + XCTAssertTrue(fm.fileExists(atPath: audioURL.path), "files without a stagingDir belong to the user and must never be deleted") + } + + // MARK: - Enqueue while running + + func testEnqueueWhileRunningAppendsToSameBatch() async { + let firstStarted = AsyncGate() + let releaseFirst = AsyncGate() + var order: [String] = [] + + let coordinator = BatchTranscriptionCoordinator(transcribe: { url in + if url.lastPathComponent == "first.m4a" { + firstStarted.open() + await releaseFirst.wait() + } + order.append(url.lastPathComponent) + return self.makeResult(text: "ok", fileName: url.lastPathComponent) + }) + + coordinator.enqueue([.init(url: self.tempAudioURL(name: "first.m4a"))]) + await firstStarted.wait() + coordinator.enqueue([.init(url: self.tempAudioURL(name: "second.m4a"))]) + releaseFirst.open() + await coordinator.waitUntilIdle() + + XCTAssertEqual(order, ["first.m4a", "second.m4a"]) + XCTAssertEqual(coordinator.items.count, 2) + XCTAssertFalse(coordinator.isRunning) + } + + // MARK: - Batch lifecycle hooks (dictation arbitration) + + func testBatchStartAndEndHooksWrapTheWholeRun() async { + var events: [String] = [] + let coordinator = BatchTranscriptionCoordinator( + transcribe: { url in + events.append("transcribe \(url.lastPathComponent)") + return self.makeResult(text: "ok", fileName: url.lastPathComponent) + }, + onBatchStart: { events.append("start") }, + onBatchEnd: { events.append("end") } + ) + + coordinator.enqueue([ + .init(url: self.tempAudioURL(name: "a.m4a")), + .init(url: self.tempAudioURL(name: "b.m4a")), + ]) + await coordinator.waitUntilIdle() + + XCTAssertEqual( + events, + ["start", "transcribe a.m4a", "transcribe b.m4a", "end"], + "start/end hooks must fire exactly once around the whole batch, not per item" + ) + } + + func testBatchEndHookFiresOnCancel() async { + var endCount = 0 + let started = AsyncGate() + let coordinator = BatchTranscriptionCoordinator( + transcribe: { url in + started.open() + try await Task.sleep(nanoseconds: 10_000_000_000) + return self.makeResult(text: "ok", fileName: url.lastPathComponent) + }, + onBatchEnd: { endCount += 1 } + ) + + coordinator.enqueue([.init(url: self.tempAudioURL(name: "a.m4a"))]) + await started.wait() + coordinator.cancel() + await coordinator.waitUntilIdle() + + XCTAssertEqual(endCount, 1, "the end hook must fire even when the batch is cancelled, or dictation stays blocked forever") + } + + // MARK: - Summary + + func testSummaryCountsReflectOutcomes() async { + let coordinator = BatchTranscriptionCoordinator(transcribe: { url in + switch url.lastPathComponent { + case "bad.m4a": throw MeetingTranscriptionService.TranscriptionError.transcriptionFailed("x") + case "silent.m4a": return self.makeResult(text: "", fileName: url.lastPathComponent) + default: return self.makeResult(text: "ok", fileName: url.lastPathComponent) + } + }) + + coordinator.enqueue([ + .init(url: self.tempAudioURL(name: "good.m4a")), + .init(url: self.tempAudioURL(name: "bad.m4a")), + .init(url: self.tempAudioURL(name: "silent.m4a")), + ]) + await coordinator.waitUntilIdle() + + XCTAssertEqual(coordinator.completedCount, 1) + XCTAssertEqual(coordinator.failedCount, 1) + XCTAssertEqual(coordinator.noSpeechCount, 1) + } +} + +/// Minimal async gate for coordinating fake transcriptions in tests. +@MainActor +private final class AsyncGate { + private var continuations: [CheckedContinuation] = [] + private var isOpen = false + + func open() { + self.isOpen = true + let waiters = self.continuations + self.continuations = [] + for c in waiters { c.resume() } + } + + func wait() async { + if self.isOpen { return } + await withCheckedContinuation { self.continuations.append($0) } + } +} diff --git a/Tests/FluidDictationIntegrationTests/PromiseDropSupportTests.swift b/Tests/FluidDictationIntegrationTests/PromiseDropSupportTests.swift new file mode 100644 index 00000000..529d558a --- /dev/null +++ b/Tests/FluidDictationIntegrationTests/PromiseDropSupportTests.swift @@ -0,0 +1,171 @@ +@testable import FluidVoice_Debug +import Foundation +import XCTest + +/// Contract tests for the testable core of the promise-aware drop path (issue #219). +/// The AppKit drop view itself needs a live drag session; these tests pin down the +/// pure logic it delegates to: strategy selection from pasteboard types, and +/// per-item staging directories that cannot collide. +final class PromiseDropSupportTests: XCTestCase { + // MARK: - Strategy selection + + func testConcreteFileURLsWinOverPromises() { + let types = ["public.file-url", "com.apple.NSFilePromiseItemMetaData", "com.apple.pasteboard.promised-file-content-type"] + XCTAssertEqual(PromiseDropSupport.strategy(forPasteboardTypes: types), .concreteFileURLs) + } + + func testPromiseTypesSelectFilePromiseStrategy() { + // Exactly what Voice Memos puts on the pasteboard (verified live 2026-07-25). + let voiceMemosTypes = [ + "com.apple.NSFilePromiseItemMetaData", + "com.apple.pasteboard.promised-file-name", + "com.apple.pasteboard.promised-suggested-file-name", + "com.apple.pasteboard.promised-file-content-type", + "Apple files promise pasteboard type", + "com.apple.pasteboard.NSFilePromiseID", + "com.apple.m4a-audio", + "com.apple.uikit.private.drag-item", + "NSPromiseContentsPboardType", + "com.apple.pasteboard.promised-file-url", + ] + XCTAssertEqual(PromiseDropSupport.strategy(forPasteboardTypes: voiceMemosTypes), .filePromise) + } + + func testUnrelatedTypesSelectNoStrategy() { + XCTAssertNil(PromiseDropSupport.strategy(forPasteboardTypes: ["public.utf8-plain-text", "public.rtf"])) + XCTAssertNil(PromiseDropSupport.strategy(forPasteboardTypes: [])) + } + + func testNonAudioVisualPromiseIsRejected() { + // A Photos-style image promise must not be accepted: staging a JPEG only + // to fail it later is worse than refusing the drag affordance up front. + let photosLikeTypes = [ + "com.apple.NSFilePromiseItemMetaData", + "com.apple.pasteboard.promised-file-content-type", + "public.jpeg", + ] + XCTAssertNil(PromiseDropSupport.strategy(forPasteboardTypes: photosLikeTypes)) + } + + func testMoviePromiseIsAccepted() { + let movieTypes = [ + "com.apple.NSFilePromiseItemMetaData", + "com.apple.pasteboard.promised-file-content-type", + "com.apple.quicktime-movie", + ] + XCTAssertEqual(PromiseDropSupport.strategy(forPasteboardTypes: movieTypes), .filePromise) + } + + // MARK: - Delivery selection + + func testTwoDistinctSameNamedModernFilesAreBothDelivered() { + // Voice Memos are commonly all titled "New Recording": two different + // memos in one drag stage into two receiver dirs with the same file + // name. Both are real files — neither may be collapsed as a duplicate. + let memoA = URL(fileURLWithPath: "/tmp/item-A/New Recording.m4a") + let memoB = URL(fileURLWithPath: "/tmp/item-B/New Recording.m4a") + let delivered = PromiseDropSupport.selectDelivery(modern: [memoA, memoB], legacy: [], data: []) + XCTAssertEqual(delivered, [memoA, memoB]) + } + + func testFallbackCopiesOfDeliveredNamesAreSuppressed() { + let modern = URL(fileURLWithPath: "/tmp/item-A/Lick Mill Blvd.m4a") + let legacyDupe = URL(fileURLWithPath: "/tmp/item-L/Lick Mill Blvd.m4a") + let dataDupe = URL(fileURLWithPath: "/tmp/item-D/Lick Mill Blvd.m4a") + let delivered = PromiseDropSupport.selectDelivery(modern: [modern], legacy: [legacyDupe], data: [dataDupe]) + XCTAssertEqual(delivered, [modern], "legacy/data copies of an already-delivered name are the same dragged item") + } + + func testFallbackOnlyDeliveryUsesLegacyThenData() { + let legacyFile = URL(fileURLWithPath: "/tmp/item-L/Memo.m4a") + let dataDupe = URL(fileURLWithPath: "/tmp/item-D/Memo.m4a") + let dataOnly = URL(fileURLWithPath: "/tmp/item-D/Other.m4a") + let delivered = PromiseDropSupport.selectDelivery(modern: [], legacy: [legacyFile], data: [dataDupe, dataOnly]) + XCTAssertEqual(delivered, [legacyFile, dataOnly]) + } + + // MARK: - Staging directories + + func testEachItemGetsAUniqueStagingDirectory() throws { + let session = try PromiseDropSupport.StagingSession() + defer { session.removeAll() } + + let dirA = try session.makeItemDirectory() + let dirB = try session.makeItemDirectory() + + XCTAssertNotEqual(dirA, dirB, "two promised files named identically must never share a staging dir") + XCTAssertTrue(FileManager.default.fileExists(atPath: dirA.path)) + XCTAssertTrue(FileManager.default.fileExists(atPath: dirB.path)) + + // Identically-named files in the two dirs must coexist. + try Data([0x01]).write(to: dirA.appendingPathComponent("New Recording.m4a")) + try Data([0x02]).write(to: dirB.appendingPathComponent("New Recording.m4a")) + XCTAssertEqual(try Data(contentsOf: dirA.appendingPathComponent("New Recording.m4a")), Data([0x01])) + XCTAssertEqual(try Data(contentsOf: dirB.appendingPathComponent("New Recording.m4a")), Data([0x02])) + } + + func testStagingDirectoriesLiveUnderTemporaryDirectory() throws { + let session = try PromiseDropSupport.StagingSession() + defer { session.removeAll() } + + let dir = try session.makeItemDirectory() + let tempPath = FileManager.default.temporaryDirectory.resolvingSymlinksInPath().path + XCTAssertTrue( + dir.resolvingSymlinksInPath().path.hasPrefix(tempPath), + "staging must be under the user temp dir, not next to user files" + ) + } + + func testRemoveAllDeletesEverything() throws { + let session = try PromiseDropSupport.StagingSession() + let dirA = try session.makeItemDirectory() + let dirB = try session.makeItemDirectory() + try Data([0x01]).write(to: dirA.appendingPathComponent("a.m4a")) + + session.removeAll() + + XCTAssertFalse(FileManager.default.fileExists(atPath: dirA.path)) + XCTAssertFalse(FileManager.default.fileExists(atPath: dirB.path)) + } + + // MARK: - Sweep selection + + func testSweepNeverIncludesADeliveredFilesDirectoryDespiteTrailingSlashDifferences() { + // Regression: dirs built with appendingPathComponent (no trailing slash) + // vs. deletingLastPathComponent() of a delivered file (trailing slash) + // compare unequal as URLs — the sweep once deleted a delivered file. + let base = URL(fileURLWithPath: "/tmp/PromiseDrop-test") + let dataDir = base.appendingPathComponent("item-data") + let legacyDir = base.appendingPathComponent("item-legacy") + let deliveredFile = URL(fileURLWithPath: "/tmp/PromiseDrop-test/item-data/", isDirectory: true) + .appendingPathComponent("Memo.m4a") + + let sweep = PromiseDropSupport.sweepableDirs(allDirs: [dataDir, legacyDir], deliveredFiles: [deliveredFile]) + + XCTAssertEqual(sweep, [legacyDir], "the delivered file's dir must never be swept") + } + + func testSweepRemovesAllDirsWhenNothingDelivered() { + let dirA = URL(fileURLWithPath: "/tmp/PromiseDrop-test/item-a") + let dirB = URL(fileURLWithPath: "/tmp/PromiseDrop-test/item-b") + XCTAssertEqual(PromiseDropSupport.sweepableDirs(allDirs: [dirA, dirB], deliveredFiles: []), [dirA, dirB]) + } + + // MARK: - Supported-file filtering for multi-file drops + + func testFilterKeepsDecodableAudioAndRejectsJunk() { + let urls = [ + URL(fileURLWithPath: "/tmp/a.m4a"), + URL(fileURLWithPath: "/tmp/b.txt"), + URL(fileURLWithPath: "/tmp/c.wav"), + URL(fileURLWithPath: "/tmp/d.pdf"), + ] + let kept = PromiseDropSupport.filterSupported(urls) + XCTAssertEqual(kept.map(\.lastPathComponent), ["a.m4a", "c.wav"]) + } + + func testFilterAcceptsUppercaseExtensions() { + let kept = PromiseDropSupport.filterSupported([URL(fileURLWithPath: "/tmp/MEMO.M4A")]) + XCTAssertEqual(kept.count, 1) + } +} From 97884b48c4e2b9b6d451dade4f03637e3f6501aa Mon Sep 17 00:00:00 2001 From: Shreeraman A K <16458670+shreeraman96@users.noreply.github.com> Date: Sun, 26 Jul 2026 12:31:42 -0700 Subject: [PATCH 2/4] fix: deliver every item of a multi-memo drag; add batch UI screenshot --- Sources/Fluid/UI/PromiseAwareDropView.swift | 63 ++++++++++++++------ assets/file_transcription_batch.png | Bin 0 -> 307601 bytes 2 files changed, 44 insertions(+), 19 deletions(-) create mode 100644 assets/file_transcription_batch.png diff --git a/Sources/Fluid/UI/PromiseAwareDropView.swift b/Sources/Fluid/UI/PromiseAwareDropView.swift index 16eec755..8b32914b 100644 --- a/Sources/Fluid/UI/PromiseAwareDropView.swift +++ b/Sources/Fluid/UI/PromiseAwareDropView.swift @@ -220,25 +220,46 @@ struct PromiseAwareDropView: NSViewRepresentable { ) // Raw-data fallback: some providers (verified for Voice Memos) - // also put the complete file bytes on the pasteboard under the - // promised content type. Memory-heavy for long recordings, so - // it is the last resort in the delivery priority order. - if let dataDir, let typeID = promisedTypeID { - let fileName = suggestedName ?? "Dropped Audio" - guard let data = pasteboard.data(forType: NSPasteboard.PasteboardType(typeID)), - !data.isEmpty else { return } - let target = dataDir.appendingPathComponent(fileName) - do { - try data.write(to: target) - DebugLogger.shared.debug( - "Raw-data fallback wrote \(data.count) bytes to \(target.lastPathComponent)", - source: "PromiseAwareDropView" - ) - } catch { - DebugLogger.shared.debug( - "Raw-data fallback write failed: \(error.localizedDescription)", - source: "PromiseAwareDropView" - ) + // also put each item's complete file bytes on the pasteboard + // under the promised content type. Read PER ITEM — the + // pasteboard-level data(forType:) only returns the first item, + // which would silently drop the rest of a multi-memo drag. + // Memory-heavy for long recordings, so it is the last resort in + // the delivery priority order. Identically-named items get + // disambiguated file names within the shared data dir. + if let dataDir { + var usedNames = Set() + for (index, item) in (pasteboard.pasteboardItems ?? []).enumerated() { + guard let itemTypeID = item.string( + forType: NSPasteboard.PasteboardType("com.apple.pasteboard.promised-file-content-type") + ) ?? promisedTypeID else { continue } + guard let data = item.data(forType: NSPasteboard.PasteboardType(itemTypeID)), + !data.isEmpty else { continue } + let itemName = item.string( + forType: NSPasteboard.PasteboardType("com.apple.pasteboard.promised-suggested-file-name") + ) ?? suggestedName ?? "Dropped Audio \(index + 1)" + var fileName = itemName + var counter = 2 + while usedNames.contains(fileName) { + let base = (itemName as NSString).deletingPathExtension + let ext = (itemName as NSString).pathExtension + fileName = ext.isEmpty ? "\(base) \(counter)" : "\(base) \(counter).\(ext)" + counter += 1 + } + usedNames.insert(fileName) + let target = dataDir.appendingPathComponent(fileName) + do { + try data.write(to: target) + DebugLogger.shared.debug( + "Raw-data fallback wrote \(data.count) bytes to \(target.lastPathComponent)", + source: "PromiseAwareDropView" + ) + } catch { + DebugLogger.shared.debug( + "Raw-data fallback write failed: \(error.localizedDescription)", + source: "PromiseAwareDropView" + ) + } } } @@ -410,7 +431,11 @@ struct PromiseAwareDropView: NSViewRepresentable { // Modern produced nothing past the grace period but a fallback // landed and its sizes are stable — use the fallback copies. let modernProducedNothing = readyModernDirs.isEmpty && elapsed > modernGrace + // The worker must be done (no in-flight token) so a multi-item + // raw-data sweep that is still writing files 3..5 isn't + // delivered after only the first items stabilized. let fallbackStable = !fallbackSizes.isEmpty && fallbackSizes == fallbackPrevSizes + && !state.hasInFlightWork if modernProducedNothing && fallbackStable { self.deliver(modern: [], legacy: legacyFiles, data: dataFiles, context: makeContext()) return diff --git a/assets/file_transcription_batch.png b/assets/file_transcription_batch.png new file mode 100644 index 0000000000000000000000000000000000000000..16bb5720968128fb7330735127d289d46a47f60b GIT binary patch literal 307601 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˧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

U zGf5dcJ2%<0D5&mV-_}HPHtV`q0=6r5Wo=B;sGA)iDEac~DIP?=3$H{Zk@RR%4d5Vp zg-`-j;Y?IImahH2LB_0+U+{KCB4QZIi_CXL7Rk&+XFn5o9KN$UeVt%Y4M}nL)fi6U zT1?9^5}6nLSe#SoZkgqN=!}(q$M5#@zs)b%uY9@675+42du!0 z#}wGjoRn-`kE-lpE!md2ZkmsWax3bNL`#kf2i(f!HFV1@g1A>a$Xs+Rb5M`kIsBns(YHniZy$8Q&{T?gw{6 z!br*!G3-hd-PU#iB(qWb6;JTDgr5N{hLYWtoXhcG{R~DUo~IeAy&7WU>>Y3^C;ST5 zX4-LHhKB9aMg?C?ZF@2G%B1N*-Fk;4Zx+PXRWH+tIk;vBDkNvdl)Bkw!^X^~j0Kd{ z)B*a~WX~qN!ZUL9RpavF-P}1x{KRPsN_l(bP*Xumw!uX8#;CAs^t@3_0z)ZQ8W_rg z?c-@8qq_-bzSzO;MYeJBqBg@R(C==~F+P@HwB`$r$MLN%dTuMdcO#DzHvhWxaNk%i z-*EBoBj~qDs~sniP4?Mw5fR#R*MF|#RrkJXu3#<%9>pT!w^>us&h)XIh|%$C&YQR^ zhSP=5dDDqY)tx8k66E)h>j6HqC7U*SF(09o#UsjfR4E)=|54;9JB`}xp4*X9)p-KT zG1&sCYG!66@!3U&vxsdmR4MbK)5rMcUYHxrG3<(Mdj!= zC&9;7tPj)1-D;Gsgez&|3wM~Z-_uA8I=^M&oh)d(gRM%mZM*`ZdqZ4eE1vyET7k#S zXi65gO87N+GJTf&o`=x}Pf=%58oNUDnNOtLmJN@qKh#@qogA}q05{`*OwVTRMf~m^ z7PrbC-n669;V@Myv{@BV0ev%0gTY%|%9XGf6qxc(;upJ2KSB6?76HWZ=g*|F)q9lu zM$eW>pJN+$@XxW0+z{cvNxv<8SIv0*o|~Eoq`%0Px9l~65KA_zRuT{hvt{-T4OOs7 zdSJc6^0QNVW1ck!u|tsTy)vmc_7N5IN>VkPKLb_E{%SPK;Ji{|<2@amR&VQ#@3*ED zJGkh~Y^jF7+|w^-cJ-h49>J)S_8;n9JudOqKukNO@~uC;e6n@%$yey8q&G26>F9s9 zE}0_-46c`?JD)&Pk1IzD|B_VRl{;bW@)?pxQush)Rca%Xl(TT&i-DP%r32K|6km$6 z_y5U(g59>G(?nK#PFa%b)Eu<7#l!?S3BEbwOAS^oyjTV2)f z*qLYOsJfPz(yBrkH%&t4at9uiI^5BGP5@j8oUvG z(za7^&!>uB9CyH_F2O%486mE}w1jCY15D(AmL84$seUYXZZTh#)7{^5n{2g*-0B86 ze?Q8qG3p;yM>+ID6JuZHOB(Ks?Jh>(f0ZY{r$RKVx^thcN|M@;!aW_e7kMWDbmQ0% z@<_(ns$g)_kw{{j`p*3Te@ZK;AvHZ}#zL%VN}w3YV_x-pWCvHn_c*Ze7lV68>JP)F z1-#GLcsopU%D{@ltuoQs<7cZ}Q-$Rj=n7lt+NsUQhyB6Hi{lpgX32G?0OBuM?UY@Z zv%kC1&GiUTe~+~Bz)YTiv!E681mfAvAzSlURO4z z24?2tb&J?~dMD8#)G3tsqUtEwi^JeAVi4BxAy7jeTEt@6dS2 zfjZM8?5*!+7Zi_dVV;hz2V6+Ya}(Z>w)7}fSHqQ~Ch@fZ(;L9vgo*NHdLku&n2F)Z zh+xTTPrDmuC3+^@L@;u<5a?%jh8diwfAIv6j1Q%i(Ri4s4^qW0-kXX9recGv z=)!pM62{T9_DD4Q!&3K@J$s7F(2D)g As4t0{a5n`a+jdLDl`iE@R9>a;c337Mj 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 KHvIXUzx+>;u+RSh literal 0 HcmV?d00001 From e90199f56d5f5006fc81c3176ade02e644ffbf23 Mon Sep 17 00:00:00 2001 From: Shreeraman A K <16458670+shreeraman96@users.noreply.github.com> Date: Sun, 26 Jul 2026 12:44:51 -0700 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20crash=20on=20multi-item=20promise=20?= =?UTF-8?q?drags=20=E2=80=94=20serialize=20pasteboard=20access?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NSPasteboard is not thread-safe: our worker's per-item reads raced the promise receivers' internal pasteboard access and crashed in the type cache (NSInternalInconsistencyException -> ggml terminate handler -> abort). All app-side reads now happen first on one thread, receivers start only afterwards on a serial queue, and every pasteboard call is wrapped in an ObjC exception catcher so a future race logs instead of killing the app. --- Sources/Fluid/Fluid-Bridging-Header.h | 1 + Sources/Fluid/ObjCExceptionCatcher.h | 18 +++ Sources/Fluid/ObjCExceptionCatcher.m | 10 ++ Sources/Fluid/UI/PromiseAwareDropView.swift | 132 ++++++++++++-------- 4 files changed, 109 insertions(+), 52 deletions(-) create mode 100644 Sources/Fluid/ObjCExceptionCatcher.h create mode 100644 Sources/Fluid/ObjCExceptionCatcher.m diff --git a/Sources/Fluid/Fluid-Bridging-Header.h b/Sources/Fluid/Fluid-Bridging-Header.h index 94f6c2e8..103728b3 100644 --- a/Sources/Fluid/Fluid-Bridging-Header.h +++ b/Sources/Fluid/Fluid-Bridging-Header.h @@ -2,5 +2,6 @@ #define FLUID_BRIDGING_HEADER_H #include "CoreAudioCaptureSupportBridge.h" +#include "ObjCExceptionCatcher.h" #endif diff --git a/Sources/Fluid/ObjCExceptionCatcher.h b/Sources/Fluid/ObjCExceptionCatcher.h new file mode 100644 index 00000000..9076cd67 --- /dev/null +++ b/Sources/Fluid/ObjCExceptionCatcher.h @@ -0,0 +1,18 @@ +#ifndef OBJC_EXCEPTION_CATCHER_H +#define OBJC_EXCEPTION_CATCHER_H + +#import + +NS_ASSUME_NONNULL_BEGIN + +/// Runs the block, catching any Objective-C exception it raises. +/// Returns the exception's description, or nil if the block completed cleanly. +/// Needed because NSPasteboard access from background threads can raise +/// NSInternalInconsistencyException on internal races, and a C++ library in the +/// process installs a terminate handler that turns any uncaught NSException +/// into abort(). +NSString *_Nullable FluidCatchObjCException(void (NS_NOESCAPE ^block)(void)); + +NS_ASSUME_NONNULL_END + +#endif diff --git a/Sources/Fluid/ObjCExceptionCatcher.m b/Sources/Fluid/ObjCExceptionCatcher.m new file mode 100644 index 00000000..6a099883 --- /dev/null +++ b/Sources/Fluid/ObjCExceptionCatcher.m @@ -0,0 +1,10 @@ +#import "ObjCExceptionCatcher.h" + +NSString *FluidCatchObjCException(void (NS_NOESCAPE ^block)(void)) { + @try { + block(); + return nil; + } @catch (NSException *exception) { + return exception.description ?: @"unknown Objective-C exception"; + } +} diff --git a/Sources/Fluid/UI/PromiseAwareDropView.swift b/Sources/Fluid/UI/PromiseAwareDropView.swift index 8b32914b..69ecaa18 100644 --- a/Sources/Fluid/UI/PromiseAwareDropView.swift +++ b/Sources/Fluid/UI/PromiseAwareDropView.swift @@ -38,7 +38,7 @@ struct PromiseAwareDropView: NSViewRepresentable { /// (e.g. by sidebar navigation) mid-drop. private static let promiseQueue: OperationQueue = { let queue = OperationQueue() - queue.maxConcurrentOperationCount = 4 + queue.maxConcurrentOperationCount = 1 return queue }() @@ -186,58 +186,59 @@ struct PromiseAwareDropView: NSViewRepresentable { Self.detachWorker { defer { state.endInFlight() } - // Modern path: each NSFilePromiseReceiver writes into its own - // item directory via the shared background operation queue. A - // directory counts as delivered only after its completion - // callback fires — polling alone could hand over a file whose - // (e.g. iCloud) download stalled mid-write. - if let receivers = pasteboard.readObjects(forClasses: [NSFilePromiseReceiver.self], options: nil) as? [NSFilePromiseReceiver] { - for receiver in receivers { - guard let dir = try? session.makeItemDirectory() else { continue } - state.registerReceiverDir(dir) - receiver.receivePromisedFiles(atDestination: dir, options: [:], operationQueue: Self.promiseQueue) { url, error in - if let error { - DebugLogger.shared.debug( - "Modern promise receiver failed [\(url.lastPathComponent)]: \(error.localizedDescription)", - source: "PromiseAwareDropView" - ) - } else { - state.markCompleted(dir) - } - } + // ORDERING MATTERS: NSPasteboard is not thread-safe, and + // receivePromisedFiles touches the pasteboard from its own + // queue. All of OUR pasteboard reads happen first, single- + // threaded, and only then do the receivers start — concurrent + // access crashed with an NSInternalInconsistencyException in + // NSPasteboard's type cache (verified live on a 3-memo drag). + // Every read is additionally wrapped in an ObjC exception + // catcher: a C++ terminate handler in the process turns any + // uncaught NSException into abort(). + + // 1. Snapshot the receiver objects and per-item metadata/bytes. + var receivers: [NSFilePromiseReceiver] = [] + var suggestedName: String? + var promisedTypeID: String? + var itemPayloads: [(name: String?, data: Data)] = [] + let readError = FluidCatchObjCException { + receivers = (pasteboard.readObjects(forClasses: [NSFilePromiseReceiver.self], options: nil) as? [NSFilePromiseReceiver]) ?? [] + suggestedName = pasteboard.string( + forType: NSPasteboard.PasteboardType("com.apple.pasteboard.promised-suggested-file-name") + ) + promisedTypeID = pasteboard.string( + forType: NSPasteboard.PasteboardType("com.apple.pasteboard.promised-file-content-type") + ) + for item in pasteboard.pasteboardItems ?? [] { + guard let itemTypeID = item.string( + forType: NSPasteboard.PasteboardType("com.apple.pasteboard.promised-file-content-type") + ) ?? promisedTypeID else { continue } + guard let data = item.data(forType: NSPasteboard.PasteboardType(itemTypeID)), + !data.isEmpty else { continue } + let name = item.string( + forType: NSPasteboard.PasteboardType("com.apple.pasteboard.promised-suggested-file-name") + ) + itemPayloads.append((name: name, data: data)) } } - - let suggestedName = pasteboard.string( - forType: NSPasteboard.PasteboardType("com.apple.pasteboard.promised-suggested-file-name") - ) - let promisedTypeID = pasteboard.string( - forType: NSPasteboard.PasteboardType("com.apple.pasteboard.promised-file-content-type") - ) + if let readError { + DebugLogger.shared.warning( + "Pasteboard read raised: \(readError)", + source: "PromiseAwareDropView" + ) + } DebugLogger.shared.debug( - "Promise drop [receivers=\(state.receiverDirsSnapshot().count), type=\(promisedTypeID ?? "?"), name=\(suggestedName ?? "?")]", + "Promise drop [receivers=\(receivers.count), items=\(itemPayloads.count), type=\(promisedTypeID ?? "?"), name=\(suggestedName ?? "?")]", source: "PromiseAwareDropView" ) - // Raw-data fallback: some providers (verified for Voice Memos) - // also put each item's complete file bytes on the pasteboard - // under the promised content type. Read PER ITEM — the - // pasteboard-level data(forType:) only returns the first item, - // which would silently drop the rest of a multi-memo drag. - // Memory-heavy for long recordings, so it is the last resort in - // the delivery priority order. Identically-named items get - // disambiguated file names within the shared data dir. - if let dataDir { + // 2. Raw-data fallback: write each item's bytes into the shared + // data dir (verified as the reliable path for Voice Memos). + // Identically-named items get disambiguated file names. + if let dataDir, !itemPayloads.isEmpty { var usedNames = Set() - for (index, item) in (pasteboard.pasteboardItems ?? []).enumerated() { - guard let itemTypeID = item.string( - forType: NSPasteboard.PasteboardType("com.apple.pasteboard.promised-file-content-type") - ) ?? promisedTypeID else { continue } - guard let data = item.data(forType: NSPasteboard.PasteboardType(itemTypeID)), - !data.isEmpty else { continue } - let itemName = item.string( - forType: NSPasteboard.PasteboardType("com.apple.pasteboard.promised-suggested-file-name") - ) ?? suggestedName ?? "Dropped Audio \(index + 1)" + for (index, payload) in itemPayloads.enumerated() { + let itemName = payload.name ?? suggestedName ?? "Dropped Audio \(index + 1)" var fileName = itemName var counter = 2 while usedNames.contains(fileName) { @@ -249,9 +250,9 @@ struct PromiseAwareDropView: NSViewRepresentable { usedNames.insert(fileName) let target = dataDir.appendingPathComponent(fileName) do { - try data.write(to: target) + try payload.data.write(to: target) DebugLogger.shared.debug( - "Raw-data fallback wrote \(data.count) bytes to \(target.lastPathComponent)", + "Raw-data fallback wrote \(payload.data.count) bytes to \(target.lastPathComponent)", source: "PromiseAwareDropView" ) } catch { @@ -263,7 +264,26 @@ struct PromiseAwareDropView: NSViewRepresentable { } } - // Legacy fallback (deprecated namesOfPromisedFilesDroppedAtDestination:), + // 3. Modern receivers, started only after our reads are done. + // Still required even when the raw-data path delivered: leaving + // a promise unresolved wedges the source app's drag machinery + // (Voice Memos refuses further drags until restarted). + for receiver in receivers { + guard let dir = try? session.makeItemDirectory() else { continue } + state.registerReceiverDir(dir) + receiver.receivePromisedFiles(atDestination: dir, options: [:], operationQueue: Self.promiseQueue) { url, error in + if let error { + DebugLogger.shared.debug( + "Modern promise receiver failed [\(url.lastPathComponent)]: \(error.localizedDescription)", + source: "PromiseAwareDropView" + ) + } else { + state.markCompleted(dir) + } + } + } + + // 4. Legacy fallback (deprecated namesOfPromisedFilesDroppedAtDestination:), // strictly last resort. A pending legacy request freezes the // source app's promise machinery until it answers (verified // live: Voice Memos unresponsive for 35-80s, blocking further @@ -288,9 +308,17 @@ struct PromiseAwareDropView: NSViewRepresentable { state.beginInFlight() Self.detachWorker { defer { state.endInFlight() } - let selector = Selector(("namesOfPromisedFilesDroppedAtDestination:")) - let names = (sender.perform(selector, with: legacyDir)? - .takeUnretainedValue() as? [String]) ?? [] + var names: [String] = [] + let legacyError = FluidCatchObjCException { + names = (sender.perform(Selector(("namesOfPromisedFilesDroppedAtDestination:")), with: legacyDir)? + .takeUnretainedValue() as? [String]) ?? [] + } + if let legacyError { + DebugLogger.shared.warning( + "Legacy promise call raised: \(legacyError)", + source: "PromiseAwareDropView" + ) + } DebugLogger.shared.debug( "Legacy promise names: \(names)", source: "PromiseAwareDropView" From 9f6032a86e93a72a26ed0c33d16ad2af11c5340a Mon Sep 17 00:00:00 2001 From: Shreeraman A K <16458670+shreeraman96@users.noreply.github.com> Date: Sun, 26 Jul 2026 17:02:56 -0700 Subject: [PATCH 4/4] fix: address xhigh code-review findings - Single MainActor arbiter for the shared ASR model: dictation intent flag set synchronously before any await closes the TOCTOU gap; batch items wait on dictation intent, live capture, and in-flight single-file transcription - Batch guard moved to every hotkey entry point (dictate/prompt/command/ rewrite), with an audible cue when dictation is blocked mid-batch - Coordinator: pending-driven processing (completed items never re-run when enqueueing after an undismissed batch) and self-draining restart (items enqueued during the cancel window are picked up, not stranded) - CancellationError rethrown unwrapped from transcribeFile (no false failure analytics) - Drop resolver: empty-delivery path no longer deletes pending receiver dirs; receivers hold in-flight tokens so slow (iCloud) promises aren't abandoned at the 30s soft timeout; failed receivers count as resolved so partial failures deliver promptly; partial-failure accounting includes raw-data item counts - Single-file drops route into the batch when anything is in flight or a finished batch is still displayed; drop errors auto-dismiss - 7 new regression tests (182 total) --- Sources/Fluid/ContentView.swift | 48 ++++++- .../BatchTranscriptionCoordinator.swift | 23 ++- .../Services/FileTranscriptionSession.swift | 37 ++++- .../MeetingTranscriptionService.swift | 5 + .../Fluid/UI/MeetingTranscriptionView.swift | 28 +++- Sources/Fluid/UI/PromiseAwareDropView.swift | 105 ++++++++++++-- Sources/Fluid/UI/PromiseDropSupport.swift | 14 ++ .../BatchTranscriptionCoordinatorTests.swift | 135 ++++++++++++++++++ .../PromiseDropSupportTests.swift | 42 ++++++ 9 files changed, 407 insertions(+), 30 deletions(-) diff --git a/Sources/Fluid/ContentView.swift b/Sources/Fluid/ContentView.swift index 9af31bf0..c9501c94 100644 --- a/Sources/Fluid/ContentView.swift +++ b/Sources/Fluid/ContentView.swift @@ -2012,6 +2012,10 @@ struct ContentView: View { // MARK: - Stop and Process Transcription private func stopAndProcessTranscription(route: DictationOutputRoute = .normal) async { + // Recording session is ending: release dictation intent so the batch arbiter + // (and any dictation restart) no longer sees dictation as active. + FileTranscriptionSession.shared.endDictationIntent() + DebugLogger.shared.debug("stopAndProcessTranscription called", source: "ContentView") DebugLogger.shared.info("Output route selected: \(route.rawValue)", source: "ContentView") self.appBench("stop_path_enter route=\(route.rawValue)") @@ -3039,12 +3043,16 @@ struct ContentView: View { // File-transcription batches drive the same shared ASR model; starting // dictation mid-batch would run concurrent inference through one model. guard !FileTranscriptionSession.isBatchTranscribing else { - DebugLogger.shared.warning( - "Dictation blocked: batch file transcription in progress", - source: "ContentView" - ) + self.notifyDictationBlockedByBatch() return } + + // Signal dictation intent synchronously, before any `await` below, so the + // batch transcribe closure's arbitration check (which also reads this flag) + // cannot race a window where neither isBatchTranscribing nor asr.isRunning + // is true yet. + FileTranscriptionSession.shared.beginDictationIntent() + let model = SettingsStore.shared.selectedSpeechModel DebugLogger.shared.info( "ContentView: startRecording() for model=\(model.displayName), supportsStreaming=\(model.supportsStreaming)", @@ -3076,6 +3084,7 @@ struct ContentView: View { }) if !self.asr.isRunning { self.menuBarManager.hideRecordingOverlayImmediately(reason: "asr_start_failed") + FileTranscriptionSession.shared.endDictationIntent() } } @@ -3310,6 +3319,12 @@ struct ContentView: View { self.menuBarManager.setOverlayMode(.command) guard !self.asr.isRunning else { return } + // Command mode starts recording directly (it does not route through + // beginDictationRecording), so it needs its own batch guard. + guard !FileTranscriptionSession.isBatchTranscribing else { + self.notifyDictationBlockedByBatch() + return + } self.advanceOverlayLifecycle() @@ -3350,6 +3365,12 @@ struct ContentView: View { self.setActiveRecordingMode(.edit) guard !self.asr.isRunning else { return } + // Rewrite/edit mode starts recording directly (it does not route through + // beginDictationRecording), so it needs its own batch guard. + guard !FileTranscriptionSession.isBatchTranscribing else { + self.notifyDictationBlockedByBatch() + return + } self.advanceOverlayLifecycle() @@ -3668,6 +3689,13 @@ extension ContentView { } private func beginDictationRecording(for slot: SettingsStore.DictationShortcutSlot, mode: ActiveRecordingMode) { + // Common chokepoint for dictate/prompt/command/rewrite hotkeys: file-transcription + // batches drive the same shared ASR model, so none of these modes may start + // while a batch is running. + guard !FileTranscriptionSession.isBatchTranscribing else { + self.notifyDictationBlockedByBatch() + return + } DebugLogger.shared.debug("Begin dictation recording for slot \(slot.rawValue)", source: "ContentView") self.appBench("begin_recording slot=\(slot.rawValue) mode=\(mode.rawValue)") if self.isOnboardingVoicePlaygroundStepActive { @@ -3717,6 +3745,18 @@ extension ContentView { self.beginDictationRecording(for: .secondary, mode: mode) } + /// Feedback when a dictation-family hotkey (dictate/prompt/command/rewrite) is + /// rejected because a file-transcription batch is running. Reuses the existing + /// stop cue rather than building new UI, so the user gets an audible signal that + /// the hotkey press had no effect instead of silence. + private func notifyDictationBlockedByBatch() { + DebugLogger.shared.warning( + "Dictation blocked: batch file transcription in progress", + source: "ContentView" + ) + TranscriptionSoundPlayer.shared.playStopSound() + } + private func appBench(_ message: String) { DebugLogger.shared.benchmark("APP_BENCH", message: message, source: "AppBenchmark") } diff --git a/Sources/Fluid/Services/BatchTranscriptionCoordinator.swift b/Sources/Fluid/Services/BatchTranscriptionCoordinator.swift index e3fb8337..2ead617d 100644 --- a/Sources/Fluid/Services/BatchTranscriptionCoordinator.swift +++ b/Sources/Fluid/Services/BatchTranscriptionCoordinator.swift @@ -153,19 +153,34 @@ final class BatchTranscriptionCoordinator: ObservableObject { self.isRunning = false self.batchTask = nil - self.resumeIdleWaiters() + + // Self-draining: items enqueued while this batch was cancelling (or right as + // it finished) are still .pending and were never picked up above. Start a + // fresh run for them so they aren't stranded. cancel() already flips + // pre-existing .pending items to .cancelled, so only genuinely new items + // land here. + if self.items.contains(where: { if case .pending = $0.status { return true } else { return false } }) { + self.startBatch() + } else { + self.resumeIdleWaiters() + } } } private func processBatch() async { - var index = 0 - while index < self.items.count { + while let index = self.nextPendingIndex() { if self.isCancelled { return } await self.processItem(at: index) - index += 1 } } + /// Finds the first item still awaiting processing. Completed/failed/cancelled items + /// are never revisited, so re-enqueuing after a finished-but-undismissed batch only + /// processes the newly appended items. + private func nextPendingIndex() -> Int? { + self.items.firstIndex { if case .pending = $0.status { return true } else { return false } } + } + private func processItem(at index: Int) async { self.items[index].status = .transcribing diff --git a/Sources/Fluid/Services/FileTranscriptionSession.swift b/Sources/Fluid/Services/FileTranscriptionSession.swift index 638c1880..bf376edb 100644 --- a/Sources/Fluid/Services/FileTranscriptionSession.swift +++ b/Sources/Fluid/Services/FileTranscriptionSession.swift @@ -22,6 +22,19 @@ final class FileTranscriptionSession { self.sharedIfCreated?.batchHolder.coordinator?.isRunning == true } + /// True from the moment a dictation/prompt/command/rewrite recording is about to + /// start until the session ends. This is the "intent to dictate" half of the + /// single-model arbiter shared with the batch transcribe closure below: it is set + /// synchronously on the main actor before any `await`, closing the TOCTOU window + /// where the batch closure's `AppServices.shared.asr.isRunning` check could pass + /// right before dictation flips `isRunning` true. + /// + /// Uses `sharedIfCreated` (not `shared`) so callers that only need to *read* the + /// flag never force-create the session/ASR service. `beginDictationIntent()` is the + /// one path allowed to force-create, since it's only called from the app's own + /// recording start path where creating the session is expected anyway. + private(set) var dictationIntent: Bool = false + let service: MeetingTranscriptionService let batchHolder: BatchCoordinatorHolder @@ -29,10 +42,14 @@ final class FileTranscriptionSession { let service = MeetingTranscriptionService(asrService: AppServices.shared.asr) self.service = service self.batchHolder = BatchCoordinatorHolder(transcribe: { url in - // Batch-vs-dictation arbitration: if the user is dictating, wait for - // the live session to finish before running this item through the - // shared model. Cancellation still interrupts the wait. - while AppServices.shared.asr.isRunning { + // Single-model arbitration: at most one of dictation, single-file + // transcription, and batch transcription may drive the shared ASR model at + // once. Wait for dictation intent (covers the TOCTOU window before + // AppServices.shared.asr.isRunning flips true), live dictation, and any + // in-flight single-file transcription. Cancellation still interrupts the wait. + while AppServices.shared.asr.isRunning + || FileTranscriptionSession.shared.dictationIntent + || service.isTranscribing { try Task.checkCancellation() try await Task.sleep(nanoseconds: 500_000_000) } @@ -40,6 +57,18 @@ final class FileTranscriptionSession { }) Self.sharedIfCreated = self } + + /// Signal that a dictation-family recording (dictate/prompt/command/rewrite) is + /// about to start. Must be called synchronously before any `await` in the caller. + func beginDictationIntent() { + self.dictationIntent = true + } + + /// Signal that the dictation-family recording session has ended (stopped, + /// cancelled, or failed to start). + func endDictationIntent() { + self.dictationIntent = false + } } /// Wraps the batch coordinator so a finished batch can be cleared and a fresh diff --git a/Sources/Fluid/Services/MeetingTranscriptionService.swift b/Sources/Fluid/Services/MeetingTranscriptionService.swift index 5a69072a..6706a78f 100644 --- a/Sources/Fluid/Services/MeetingTranscriptionService.swift +++ b/Sources/Fluid/Services/MeetingTranscriptionService.swift @@ -375,6 +375,11 @@ final class MeetingTranscriptionService: ObservableObject { FileTranscriptionHistoryStore.shared.addEntry(result) return result + } catch is CancellationError { + // Cooperative cancellation (batch cancel, app teardown, etc.) is not a + // transcription failure: don't surface it as an error or fire a false + // failure analytics event. + throw CancellationError() } catch let error as TranscriptionError { self.error = error.localizedDescription AnalyticsService.shared.capture( diff --git a/Sources/Fluid/UI/MeetingTranscriptionView.swift b/Sources/Fluid/UI/MeetingTranscriptionView.swift index 5364c1cd..ce8d0a5a 100644 --- a/Sources/Fluid/UI/MeetingTranscriptionView.swift +++ b/Sources/Fluid/UI/MeetingTranscriptionView.swift @@ -26,6 +26,7 @@ struct MeetingTranscriptionView: View { @State private var showingCopyConfirmation = false @State private var isDropTargeted = false @State private var dropErrorMessage: String? + @State private var dropErrorGeneration = 0 enum ExportFormat: String, CaseIterable { case text = "Text (.txt)" @@ -107,7 +108,7 @@ struct MeetingTranscriptionView: View { PromiseAwareDropView( onTargetedChange: { self.isDropTargeted = $0 }, onFiles: { self.handleIncomingFiles($0) }, - onError: { self.dropErrorMessage = $0 } + onError: { self.showDropError($0) } ) ) .background(self.theme.palette.windowBackground) @@ -716,8 +717,13 @@ struct MeetingTranscriptionView: View { guard !files.isEmpty else { return } self.dropErrorMessage = nil - let batchIsRunning = self.batchHolder.coordinator?.isRunning == true - if files.count == 1, let file = files.first, file.stagingDir == nil, !batchIsRunning { + // Single concrete file goes through the fast path only when there's no batch + // (running or finished-but-undismissed — isBatchActive covers both) and no + // single-file transcription already in flight; otherwise it's routed into the + // coordinator, which either appends to the live batch or shows up as a fresh + // row so the self-draining batch picks it up. + if files.count == 1, let file = files.first, file.stagingDir == nil, + !self.isBatchActive, !self.transcriptionService.isTranscribing { self.selectedFileURL = file.url self.transcriptionService.reset() return @@ -728,6 +734,22 @@ struct MeetingTranscriptionView: View { /// Clears the batch list and resets shared service state so a subsequent batch /// starts fresh and no stale single-file result lingers. + /// Shows a drop error and auto-dismisses it after a few seconds. Promise + /// resolution can report errors up to two minutes after the drop; without + /// auto-dismissal a stale red card would appear over an already-successful + /// batch and stick around until manually closed. + private func showDropError(_ message: String) { + self.dropErrorMessage = message + self.dropErrorGeneration += 1 + let generation = self.dropErrorGeneration + Task { @MainActor in + try? await Task.sleep(nanoseconds: 6_000_000_000) + if self.dropErrorGeneration == generation { + self.dropErrorMessage = nil + } + } + } + private func dismissBatch() { self.batchHolder.clear() self.transcriptionService.reset() diff --git a/Sources/Fluid/UI/PromiseAwareDropView.swift b/Sources/Fluid/UI/PromiseAwareDropView.swift index 69ecaa18..2a520882 100644 --- a/Sources/Fluid/UI/PromiseAwareDropView.swift +++ b/Sources/Fluid/UI/PromiseAwareDropView.swift @@ -231,6 +231,7 @@ struct PromiseAwareDropView: NSViewRepresentable { "Promise drop [receivers=\(receivers.count), items=\(itemPayloads.count), type=\(promisedTypeID ?? "?"), name=\(suggestedName ?? "?")]", source: "PromiseAwareDropView" ) + state.setPayloadCount(itemPayloads.count) // 2. Raw-data fallback: write each item's bytes into the shared // data dir (verified as the reliable path for Voice Memos). @@ -271,12 +272,19 @@ struct PromiseAwareDropView: NSViewRepresentable { for receiver in receivers { guard let dir = try? session.makeItemDirectory() else { continue } state.registerReceiverDir(dir) + // A per-receiver token: the soft timeout must not abandon a + // promise that is still downloading (e.g. iCloud taking 45s) + // just because the outer worker thread already finished + // (finding F8). Released on both the success and error paths. + state.beginInFlight() receiver.receivePromisedFiles(atDestination: dir, options: [:], operationQueue: Self.promiseQueue) { url, error in + defer { state.endInFlight() } if let error { DebugLogger.shared.debug( "Modern promise receiver failed [\(url.lastPathComponent)]: \(error.localizedDescription)", source: "PromiseAwareDropView" ) + state.markFailed(dir) } else { state.markCompleted(dir) } @@ -340,7 +348,9 @@ struct PromiseAwareDropView: NSViewRepresentable { private let lock = NSLock() private var receiverDirs: [URL] = [] private var completed: Set = [] + private var failed: Set = [] private var inFlightCount = 0 + private var payloadCount = 0 func registerReceiverDir(_ dir: URL) { self.lock.lock() @@ -366,6 +376,37 @@ struct PromiseAwareDropView: NSViewRepresentable { return self.completed } + /// Marks a receiver as resolved-but-failed. A failed receiver's + /// promise has already answered (with an error), so — unlike a + /// still-pending one — its staging dir is safe to sweep immediately + /// and it counts toward "every receiver resolved" for delivery + /// gating (finding F9). + func markFailed(_ dir: URL) { + self.lock.lock() + defer { self.lock.unlock() } + self.failed.insert(dir) + } + + func failedSnapshot() -> Set { + self.lock.lock() + defer { self.lock.unlock() } + return self.failed + } + + /// Records the raw-data item count once, so a receiver-less + /// multi-item drop can still detect a partial delivery (finding F11). + func setPayloadCount(_ count: Int) { + self.lock.lock() + defer { self.lock.unlock() } + self.payloadCount = count + } + + func payloadCountValue() -> Int { + self.lock.lock() + defer { self.lock.unlock() } + return self.payloadCount + } + func beginInFlight() { self.lock.lock() defer { self.lock.unlock() } @@ -417,10 +458,16 @@ struct PromiseAwareDropView: NSViewRepresentable { func makeContext() -> DeliveryContext { let receiverDirs = state.receiverDirsSnapshot() let completed = state.completedSnapshot() + let failed = state.failedSnapshot() return DeliveryContext( allDirs: receiverDirs + [legacyDir, dataDir].compactMap(\.self), - pendingReceiverDirs: receiverDirs.filter { !completed.contains($0) }, - totalExpected: max(receiverDirs.count, 1), + // A failed receiver has already answered (with an error), so + // unlike a still-pending one its dir is safe to sweep now. + pendingReceiverDirs: receiverDirs.filter { !completed.contains($0) && !failed.contains($0) }, + // The raw-data item count also bounds expectations: a + // receiver-less multi-item drop that partially lands must + // still surface a partial-failure error (finding F11). + totalExpected: max(receiverDirs.count, state.payloadCountValue(), 1), session: session, onFiles: onFiles, onError: onError @@ -439,26 +486,36 @@ struct PromiseAwareDropView: NSViewRepresentable { // truncated file just because its size held still between polls. let receiverDirs = state.receiverDirsSnapshot() let readyModernDirs = state.completedSnapshot() + let failedModernDirs = state.failedSnapshot() let modernFiles = self.listFiles(in: receiverDirs.filter(readyModernDirs.contains)) let legacyFiles = self.listFiles(in: [legacyDir].compactMap(\.self)) let dataFiles = self.listFiles(in: [dataDir].compactMap(\.self)) let fallbackSizes = self.sizeMap(for: legacyFiles + dataFiles) - // Modern succeeded outright: every registered receiver completed. - // (Receivers register in one tight loop with no pasteboard call - // in between, so a partially-registered snapshot is a micro-race + // "Resolved" = completed OR failed: a failed receiver's promise + // has already answered, so it can never flip to completed later + // (finding F9) — waiting on it would spin the full soft timeout. + let resolvedCount = readyModernDirs.count + failedModernDirs.count + let allReceiversResolved = !receiverDirs.isEmpty && resolvedCount >= receiverDirs.count + + // Modern succeeded outright: every registered receiver resolved, + // at least one completed, and it produced files. (Receivers + // register in one tight loop with no pasteboard call in + // between, so a partially-registered snapshot is a micro-race // at worst; completion still requires each dir's callback.) - let modernComplete = !receiverDirs.isEmpty - && readyModernDirs.count >= receiverDirs.count - && !modernFiles.isEmpty + let modernComplete = allReceiversResolved && !readyModernDirs.isEmpty && !modernFiles.isEmpty if modernComplete { self.deliver(modern: modernFiles, legacy: legacyFiles, data: dataFiles, context: makeContext()) return } - // Modern produced nothing past the grace period but a fallback - // landed and its sizes are stable — use the fallback copies. - let modernProducedNothing = readyModernDirs.isEmpty && elapsed > modernGrace + // Modern produced nothing — either no receivers were ever + // registered, or every registered receiver resolved and none + // completed — past the grace period, but a fallback landed and + // its sizes are stable — use the fallback copies. + let modernExhaustedWithNoWins = receiverDirs.isEmpty + || (allReceiversResolved && readyModernDirs.isEmpty) + let modernProducedNothing = modernExhaustedWithNoWins && elapsed > modernGrace // The worker must be done (no in-flight token) so a multi-item // raw-data sweep that is still writing files 3..5 isn't // delivered after only the first items stabilized. @@ -520,7 +577,23 @@ struct PromiseAwareDropView: NSViewRepresentable { let result = supported.map { (url: $0, stagingDir: $0.deletingLastPathComponent()) } if result.isEmpty { - context.session.removeAll() + // Same pending-respecting sweep as the non-empty branch below: + // an empty result must not delete staging dirs whose receiver + // promise hasn't completed yet (finding F1) — removeAll() used + // to nuke the whole session root, pending dirs included, which + // wedges the source app's drag machinery. + for dir in PromiseDropSupport.dirsSafeToRemoveNow( + allDirs: context.allDirs, + deliveredFiles: [], + pendingDirs: context.pendingReceiverDirs + ) { + try? FileManager.default.removeItem(at: dir) + } + if context.pendingReceiverDirs.isEmpty { + context.session.removeAll() + } else { + self.cleanUpLater(pendingDirs: context.pendingReceiverDirs) + } let reason = selected.isEmpty ? "No files could be read from the drop." : "The dropped files are not a supported format." @@ -535,9 +608,11 @@ struct PromiseAwareDropView: NSViewRepresentable { // files are throwaway copies) and keeps the temp dir clean. The // batch coordinator removes the delivered dirs (and then the empty // session root) after each item's transcription. - let pendingPaths = Set(context.pendingReceiverDirs.map(\.standardizedFileURL.path)) - for dir in PromiseDropSupport.sweepableDirs(allDirs: context.allDirs, deliveredFiles: supported) - where !pendingPaths.contains(dir.standardizedFileURL.path) { + for dir in PromiseDropSupport.dirsSafeToRemoveNow( + allDirs: context.allDirs, + deliveredFiles: supported, + pendingDirs: context.pendingReceiverDirs + ) { try? FileManager.default.removeItem(at: dir) } diff --git a/Sources/Fluid/UI/PromiseDropSupport.swift b/Sources/Fluid/UI/PromiseDropSupport.swift index 9fdc80e7..a7078b33 100644 --- a/Sources/Fluid/UI/PromiseDropSupport.swift +++ b/Sources/Fluid/UI/PromiseDropSupport.swift @@ -65,6 +65,20 @@ nonisolated enum PromiseDropSupport { return allDirs.filter { !deliveredDirPaths.contains($0.standardizedFileURL.path) } } + /// Staging dirs safe to delete right now: swept per `sweepableDirs`, minus + /// any dir whose receiver promise hasn't completed yet. + /// + /// Pending receiver dirs must never be removed while pending — the source + /// app (e.g. Voice Memos) may still be writing into them, and deleting the + /// destination out from under an in-flight `NSFilePromiseReceiver` wedges + /// its drag machinery until restart. Callers are expected to defer removal + /// of the excluded dirs until the pending promises resolve. + static func dirsSafeToRemoveNow(allDirs: [URL], deliveredFiles: [URL], pendingDirs: [URL]) -> [URL] { + let pendingPaths = Set(pendingDirs.map { $0.standardizedFileURL.path }) + return sweepableDirs(allDirs: allDirs, deliveredFiles: deliveredFiles) + .filter { !pendingPaths.contains($0.standardizedFileURL.path) } + } + /// Merges the three promise-delivery paths into the final file list. /// /// Every modern-receiver file is delivered: each receiver stages into its own diff --git a/Tests/FluidDictationIntegrationTests/BatchTranscriptionCoordinatorTests.swift b/Tests/FluidDictationIntegrationTests/BatchTranscriptionCoordinatorTests.swift index c8ddf44f..8bf18da6 100644 --- a/Tests/FluidDictationIntegrationTests/BatchTranscriptionCoordinatorTests.swift +++ b/Tests/FluidDictationIntegrationTests/BatchTranscriptionCoordinatorTests.swift @@ -340,6 +340,141 @@ final class BatchTranscriptionCoordinatorTests: XCTestCase { XCTAssertEqual(endCount, 1, "the end hook must fire even when the batch is cancelled, or dictation stays blocked forever") } + // MARK: - Enqueue after a finished batch (F5/F15a) + + func testEnqueueAfterFinishedBatchProcessesOnlyNewItems() async { + var transcribedPaths: [String] = [] + let coordinator = BatchTranscriptionCoordinator(transcribe: { url in + transcribedPaths.append(url.lastPathComponent) + return self.makeResult(text: "ok", fileName: url.lastPathComponent) + }) + + coordinator.enqueue([.init(url: self.tempAudioURL(name: "first.m4a"))]) + await coordinator.waitUntilIdle() + XCTAssertEqual(transcribedPaths, ["first.m4a"]) + guard case .completed = coordinator.items[0].status else { + return XCTFail("first item should complete, got \(coordinator.items[0].status)") + } + + // Batch finished but items weren't dismissed (dismissBatch/clear() wasn't + // called) — enqueue must not re-walk from index 0 and re-run "first.m4a". + coordinator.enqueue([.init(url: self.tempAudioURL(name: "second.m4a"))]) + await coordinator.waitUntilIdle() + + XCTAssertEqual( + transcribedPaths, + ["first.m4a", "second.m4a"], + "re-enqueueing after a finished-but-undismissed batch must not re-run completed items" + ) + XCTAssertEqual(coordinator.items.count, 2) + guard case .completed = coordinator.items[0].status else { + return XCTFail("completed item must keep its status, got \(coordinator.items[0].status)") + } + guard case .completed = coordinator.items[1].status else { + return XCTFail("new item should complete, got \(coordinator.items[1].status)") + } + } + + // MARK: - Enqueue during the cancel window (F6/F15b) + + func testEnqueueDuringCancelWindowIsNotStranded() async { + let started = AsyncGate() + let releaseInFlight = AsyncGate() + var transcribedPaths: [String] = [] + + let coordinator = BatchTranscriptionCoordinator(transcribe: { url in + if url.lastPathComponent == "in-flight.m4a" { + started.open() + await releaseInFlight.wait() + } + transcribedPaths.append(url.lastPathComponent) + return self.makeResult(text: "ok", fileName: url.lastPathComponent) + }) + + coordinator.enqueue([.init(url: self.tempAudioURL(name: "in-flight.m4a"))]) + await started.wait() + + // Cancel while the in-flight item is still gated/running. + coordinator.cancel() + + // Enqueue a new item while the cancelled batch's in-flight item hasn't + // finished yet — it must not be stranded. + coordinator.enqueue([.init(url: self.tempAudioURL(name: "after-cancel.m4a"))]) + + // Now let the in-flight (cancelled) item finish. + releaseInFlight.open() + + await coordinator.waitUntilIdle() + + guard case .cancelled = coordinator.items[0].status else { + return XCTFail("in-flight item must be .cancelled, got \(coordinator.items[0].status)") + } + guard case .completed = coordinator.items[1].status else { + return XCTFail("item enqueued during the cancel window must eventually process, got \(coordinator.items[1].status)") + } + XCTAssertEqual(transcribedPaths, ["in-flight.m4a", "after-cancel.m4a"]) + XCTAssertFalse(coordinator.isRunning) + } + + // MARK: - BatchCoordinatorHolder.clear() while running (F15c) + + func testHolderClearWhileRunningCancelsAndFreshEnqueueWorksAfterward() async { + let started = AsyncGate() + var transcribedPaths: [String] = [] + + let holder = BatchCoordinatorHolder(transcribe: { url in + if url.lastPathComponent == "long-running.m4a" { + started.open() + try await Task.sleep(nanoseconds: 10_000_000_000) + } + transcribedPaths.append(url.lastPathComponent) + return self.makeResult(text: "ok", fileName: url.lastPathComponent) + }) + + holder.enqueue([.init(url: self.tempAudioURL(name: "long-running.m4a"))]) + await started.wait() + + guard let orphanedCoordinator = holder.coordinator else { + return XCTFail("coordinator must exist while a batch is running") + } + holder.clear() + + XCTAssertNil(holder.coordinator, "clear() must drop the coordinator reference") + await orphanedCoordinator.waitUntilIdle() + XCTAssertFalse(orphanedCoordinator.isRunning, "clear() must cancel the orphaned batch, not leave it running") + guard case .cancelled = orphanedCoordinator.items[0].status else { + return XCTFail("orphaned in-flight item must be .cancelled, got \(orphanedCoordinator.items[0].status)") + } + XCTAssertFalse(transcribedPaths.contains("long-running.m4a"), "cancelled item must never reach a completed outcome") + + // A subsequent enqueue must work on a fresh coordinator. + holder.enqueue([.init(url: self.tempAudioURL(name: "fresh.m4a"))]) + await holder.coordinator?.waitUntilIdle() + + guard case .completed = holder.coordinator?.items.first?.status else { + return XCTFail("fresh coordinator after clear() must process normally") + } + } + + // MARK: - Cancellation surfaced from the transcribe closure's wait loop (F15d) + + func testCancellationThrownFromTranscribeClosureMarksItemCancelled() async { + let coordinator = BatchTranscriptionCoordinator(transcribe: { _ in + // Simulates the dictation-arbitration wait loop observing cancellation + // (e.g. FileTranscriptionSession's `try Task.checkCancellation()` while + // waiting for dictation/single-file transcription to finish) before ever + // calling into the transcription service. + throw CancellationError() + }) + + coordinator.enqueue([.init(url: self.tempAudioURL(name: "gated.m4a"))]) + await coordinator.waitUntilIdle() + + guard case .cancelled = coordinator.items[0].status else { + return XCTFail("a CancellationError thrown while waiting must mark the item .cancelled, got \(coordinator.items[0].status)") + } + } + // MARK: - Summary func testSummaryCountsReflectOutcomes() async { diff --git a/Tests/FluidDictationIntegrationTests/PromiseDropSupportTests.swift b/Tests/FluidDictationIntegrationTests/PromiseDropSupportTests.swift index 529d558a..be07128d 100644 --- a/Tests/FluidDictationIntegrationTests/PromiseDropSupportTests.swift +++ b/Tests/FluidDictationIntegrationTests/PromiseDropSupportTests.swift @@ -151,6 +151,48 @@ final class PromiseDropSupportTests: XCTestCase { XCTAssertEqual(PromiseDropSupport.sweepableDirs(allDirs: [dirA, dirB], deliveredFiles: []), [dirA, dirB]) } + // MARK: - dirsSafeToRemoveNow (findings F1 / F9) + + func testDirsSafeToRemoveNowExcludesPendingReceiverDirsEvenWhenNothingDelivered() { + // Regression for F1: an empty delivery result must not sweep a pending + // receiver's staging dir — deleting the destination out from under an + // in-flight NSFilePromiseReceiver wedges the source app's drag machinery. + let pendingDir = URL(fileURLWithPath: "/tmp/PromiseDrop-test/item-pending") + let deadDir = URL(fileURLWithPath: "/tmp/PromiseDrop-test/item-dead") + + let safe = PromiseDropSupport.dirsSafeToRemoveNow( + allDirs: [pendingDir, deadDir], + deliveredFiles: [], + pendingDirs: [pendingDir] + ) + + XCTAssertEqual(safe, [deadDir], "a still-pending receiver dir must never be swept, even with an empty delivery") + } + + func testDirsSafeToRemoveNowExcludesPendingDirsAlongsideDeliveredFiles() { + let deliveredFile = URL(fileURLWithPath: "/tmp/PromiseDrop-test/item-a/Memo.m4a") + let deliveredDir = URL(fileURLWithPath: "/tmp/PromiseDrop-test/item-a") + let pendingDir = URL(fileURLWithPath: "/tmp/PromiseDrop-test/item-pending") + let loserDir = URL(fileURLWithPath: "/tmp/PromiseDrop-test/item-loser") + + let safe = PromiseDropSupport.dirsSafeToRemoveNow( + allDirs: [deliveredDir, pendingDir, loserDir], + deliveredFiles: [deliveredFile], + pendingDirs: [pendingDir] + ) + + XCTAssertEqual(safe, [loserDir]) + } + + func testDirsSafeToRemoveNowAllowsEverythingWhenNoPendingDirs() { + let dirA = URL(fileURLWithPath: "/tmp/PromiseDrop-test/item-a") + let dirB = URL(fileURLWithPath: "/tmp/PromiseDrop-test/item-b") + + let safe = PromiseDropSupport.dirsSafeToRemoveNow(allDirs: [dirA, dirB], deliveredFiles: [], pendingDirs: []) + + XCTAssertEqual(safe, [dirA, dirB]) + } + // MARK: - Supported-file filtering for multi-file drops func testFilterKeepsDecodableAudioAndRejectsJunk() {