78 lines · 3.0 KB · Swift
RawDownload
import Foundation public struct KiloResolvedBearerToken: Sendable, Equatable {    public let token: String    public let sourceLabel: String     public init(token: String, sourceLabel: String) {        self.token = token        self.sourceLabel = sourceLabel    }} /// Resolves the Kilo bearer token shared by usage fetches and organization discovery.////// Behavior mirrors the per-strategy resolution in `KiloProviderDescriptor`:/// - `.api`: explicit `apiKey`, falling back to `KILO_API_KEY` env var./// - `.cli`: token from `~/.local/share/kilo/auth.json` (`kilo.access`)./// - `.auto`: API first, falling back to CLI when API credentials are missing.public enum KiloBearerTokenResolver {    public static func resolve(        source: KiloUsageDataSource,        apiKey: String?,        environment: [String: String] = ProcessInfo.processInfo.environment) throws -> KiloResolvedBearerToken    {        switch source {        case .api:            return try self.resolveAPI(apiKey: apiKey, environment: environment)        case .cli:            return try self.resolveCLI(environment: environment)        case .auto:            if let resolved = try? self.resolveAPI(apiKey: apiKey, environment: environment) {                return resolved            }            return try self.resolveCLI(environment: environment)        }    }     private static func resolveAPI(        apiKey: String?,        environment: [String: String]) throws -> KiloResolvedBearerToken    {        let direct = KiloSettingsReader.cleaned(apiKey)        let envValue = KiloSettingsReader.cleaned(environment[KiloSettingsReader.apiTokenKey])        if let token = direct ?? envValue {            return KiloResolvedBearerToken(token: token, sourceLabel: "api")        }        throw KiloUsageError.missingCredentials    }     private static func resolveCLI(        environment: [String: String]) throws -> KiloResolvedBearerToken    {        let url = self.authFileURL(environment: environment)        guard FileManager.default.fileExists(atPath: url.path) else {            throw KiloUsageError.cliSessionMissing(url.path)        }        let data: Data        do {            data = try Data(contentsOf: url)        } catch {            throw KiloUsageError.cliSessionUnreadable(url.path)        }        guard let token = KiloSettingsReader.parseAuthToken(data: data) else {            throw KiloUsageError.cliSessionInvalid(url.path)        }        return KiloResolvedBearerToken(token: token, sourceLabel: "cli")    }     static func authFileURL(environment: [String: String]) -> URL {        if let home = KiloSettingsReader.cleaned(environment["HOME"]) {            let expandedHome = NSString(string: home).expandingTildeInPath            return KiloSettingsReader.defaultAuthFileURL(                homeDirectory: URL(fileURLWithPath: expandedHome, isDirectory: true))        }        return KiloSettingsReader.defaultAuthFileURL(            homeDirectory: FileManager.default.homeDirectoryForCurrentUser)    }}