import Foundation public enum DeepLinkRoute: Sendable, Equatable { case agent(AgentDeepLink) } public struct AgentDeepLink: Codable, Sendable, Equatable { public let message: String public let sessionKey: String? public let thinking: String? public let deliver: Bool public let to: String? public let channel: String? public let timeoutSeconds: Int? public let key: String? public init( message: String, sessionKey: String?, thinking: String?, deliver: Bool, to: String?, channel: String?, timeoutSeconds: Int?, key: String?) { self.message = message self.sessionKey = sessionKey self.thinking = thinking self.deliver = deliver self.to = to self.channel = channel self.timeoutSeconds = timeoutSeconds self.key = key } } public enum DeepLinkParser { public static func parse(_ url: URL) -> DeepLinkRoute? { guard url.scheme?.lowercased() == "clawdbot" else { return nil } guard let host = url.host?.lowercased(), !host.isEmpty else { return nil } guard let comps = URLComponents(url: url, resolvingAgainstBaseURL: false) else { return nil } let query = (comps.queryItems ?? []).reduce(into: [String: String]()) { dict, item in guard let value = item.value else { return } dict[item.name] = value } switch host { case "agent": guard let message = query["message"], !message.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return nil } let deliver = (query["deliver"] as NSString?)?.boolValue ?? false let timeoutSeconds = query["timeoutSeconds"].flatMap { Int($0) }.flatMap { $0 >= 0 ? $0 : nil } return .agent( .init( message: message, sessionKey: query["sessionKey"], thinking: query["thinking"], deliver: deliver, to: query["to"], channel: query["channel"], timeoutSeconds: timeoutSeconds, key: query["key"])) default: return nil } } }