import AppKit @MainActor enum AppLauncher { static func launch(_ url: URL) async throws { let configuration = NSWorkspace.OpenConfiguration() configuration.activates = true configuration.promptsUserIfNeeded = false try await withCheckedThrowingContinuation { (continuation: CheckedContinuation) in NSWorkspace.shared.openApplication(at: url, configuration: configuration) { _, error in // AppKit calls this completion on a concurrent queue; only resume the continuation here. if let error { continuation.resume(throwing: error) } else { continuation.resume() } } } } static func quit(_ url: URL) throws { let path = url.standardizedFileURL.resolvingSymlinksInPath().path for application in NSWorkspace.shared.runningApplications { guard application.bundleURL?.standardizedFileURL.resolvingSymlinksInPath().path == path, !application.isTerminated else { continue } guard application.terminate() else { throw NSError(domain: "Conjure", code: 1, userInfo: [ NSLocalizedDescriptionKey: "The application refused the quit request. Save your work and quit it manually." ]) } } } }