mirror of
https://github.com/samsonjs/Peekaboo.git
synced 2026-04-27 15:07:41 +00:00
- Remove empty string from item_type enum to prevent undefined values - Add defensive programming to buildSwiftCliArgs to filter out undefined/null values - Improve item type determination logic with explicit string checks - Add debug logging for Swift CLI arguments - Fix double --json-output flag issue This fixes the "Unknown operation: undefined" error when calling list with server_status. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
108 lines
No EOL
2.4 KiB
Swift
108 lines
No EOL
2.4 KiB
Swift
import Foundation
|
|
import ArgumentParser
|
|
|
|
// MARK: - Adapter for AsyncParsableCommand to ParsableCommand bridge
|
|
|
|
protocol AsyncRunnable {
|
|
func runAsync() async throws
|
|
}
|
|
|
|
// Thread-safe result container
|
|
private final class ResultBox<T>: @unchecked Sendable {
|
|
private var _result: Result<T, Error>?
|
|
private let lock = NSLock()
|
|
|
|
var result: Result<T, Error>? {
|
|
get {
|
|
lock.lock()
|
|
defer { lock.unlock() }
|
|
return _result
|
|
}
|
|
set {
|
|
lock.lock()
|
|
defer { lock.unlock() }
|
|
_result = newValue
|
|
}
|
|
}
|
|
}
|
|
|
|
// Helper to run async code synchronously
|
|
private func runAsyncBlocking<T: Sendable>(_ asyncWork: @escaping @Sendable () async throws -> T) throws -> T {
|
|
let resultBox = ResultBox<T>()
|
|
let semaphore = DispatchSemaphore(value: 0)
|
|
|
|
Task.detached {
|
|
do {
|
|
let value = try await asyncWork()
|
|
resultBox.result = .success(value)
|
|
} catch {
|
|
resultBox.result = .failure(error)
|
|
}
|
|
semaphore.signal()
|
|
}
|
|
|
|
semaphore.wait()
|
|
|
|
switch resultBox.result {
|
|
case .success(let value):
|
|
return value
|
|
case .failure(let error):
|
|
throw error
|
|
case .none:
|
|
fatalError("Async operation did not complete")
|
|
}
|
|
}
|
|
|
|
extension PeekabooCommand {
|
|
func run() throws {
|
|
try runAsyncBlocking {
|
|
try await (self as AsyncRunnable).runAsync()
|
|
return ()
|
|
}
|
|
}
|
|
}
|
|
|
|
extension ImageCommand {
|
|
func run() throws {
|
|
try runAsyncBlocking {
|
|
try await (self as AsyncRunnable).runAsync()
|
|
return ()
|
|
}
|
|
}
|
|
}
|
|
|
|
extension ListCommand {
|
|
func run() throws {
|
|
try runAsyncBlocking {
|
|
try await (self as AsyncRunnable).runAsync()
|
|
return ()
|
|
}
|
|
}
|
|
}
|
|
|
|
extension AppsSubcommand {
|
|
func run() throws {
|
|
try runAsyncBlocking {
|
|
try await (self as AsyncRunnable).runAsync()
|
|
return ()
|
|
}
|
|
}
|
|
}
|
|
|
|
extension WindowsSubcommand {
|
|
func run() throws {
|
|
try runAsyncBlocking {
|
|
try await (self as AsyncRunnable).runAsync()
|
|
return ()
|
|
}
|
|
}
|
|
}
|
|
|
|
extension ServerStatusSubcommand {
|
|
func run() throws {
|
|
try runAsyncBlocking {
|
|
try await (self as AsyncRunnable).runAsync()
|
|
return ()
|
|
}
|
|
}
|
|
} |