chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import Foundation
|
||||
|
||||
public enum CursorProviderDescriptor {
|
||||
public static let descriptor: ProviderDescriptor = Self.makeDescriptor()
|
||||
|
||||
static func makeDescriptor() -> ProviderDescriptor {
|
||||
ProviderDescriptor(
|
||||
id: .cursor,
|
||||
metadata: ProviderMetadata(
|
||||
id: .cursor,
|
||||
displayName: "Cursor",
|
||||
sessionLabel: "Total",
|
||||
weeklyLabel: "Auto",
|
||||
opusLabel: "API",
|
||||
supportsOpus: true,
|
||||
supportsCredits: true,
|
||||
creditsHint: "On-demand usage beyond included plan limits.",
|
||||
toggleTitle: "Show Cursor usage",
|
||||
cliName: "cursor",
|
||||
defaultEnabled: false,
|
||||
isPrimaryProvider: false,
|
||||
usesAccountFallback: false,
|
||||
browserCookieOrder: ProviderBrowserCookieDefaults.cursorCookieImportOrder
|
||||
?? ProviderBrowserCookieDefaults.defaultImportOrder,
|
||||
dashboardURL: "https://cursor.com/dashboard?tab=usage",
|
||||
statusPageURL: "https://status.cursor.com",
|
||||
statusLinkURL: nil),
|
||||
branding: ProviderBranding(
|
||||
iconStyle: .cursor,
|
||||
iconResourceName: "ProviderIcon-cursor",
|
||||
color: ProviderColor(red: 0 / 255, green: 191 / 255, blue: 165 / 255)),
|
||||
tokenCost: ProviderTokenCostConfig(
|
||||
supportsTokenCost: false,
|
||||
noDataMessage: { "Cursor cost summary is not supported." }),
|
||||
fetchPlan: ProviderFetchPlan(
|
||||
sourceModes: [.auto, .cli, .web],
|
||||
pipeline: ProviderFetchPipeline(resolveStrategies: { _ in [CursorStatusFetchStrategy()] })),
|
||||
cli: ProviderCLIConfig(
|
||||
name: "cursor",
|
||||
versionDetector: nil))
|
||||
}
|
||||
}
|
||||
|
||||
struct CursorStatusFetchStrategy: ProviderFetchStrategy {
|
||||
let id: String = "cursor.web"
|
||||
let kind: ProviderFetchKind = .web
|
||||
|
||||
func isAvailable(_ context: ProviderFetchContext) async -> Bool {
|
||||
guard context.settings?.cursor?.cookieSource != .off else { return false }
|
||||
return true
|
||||
}
|
||||
|
||||
func fetch(_ context: ProviderFetchContext) async throws -> ProviderFetchResult {
|
||||
let probe = CursorStatusProbe(browserDetection: context.browserDetection)
|
||||
let manual = Self.manualCookieHeader(from: context)
|
||||
let snap = try await probe.fetch(cookieHeaderOverride: manual)
|
||||
return self.makeResult(
|
||||
usage: snap.toUsageSnapshot(),
|
||||
sourceLabel: "web")
|
||||
}
|
||||
|
||||
func shouldFallback(on _: Error, context _: ProviderFetchContext) -> Bool {
|
||||
false
|
||||
}
|
||||
|
||||
private static func manualCookieHeader(from context: ProviderFetchContext) -> String? {
|
||||
guard context.settings?.cursor?.cookieSource == .manual else { return nil }
|
||||
return CookieHeaderNormalizer.normalize(context.settings?.cursor?.manualCookieHeader)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import Foundation
|
||||
|
||||
/// Request usage snapshot for legacy Cursor plans (request-based instead of token-based).
|
||||
public struct CursorRequestUsage: Codable, Sendable {
|
||||
/// Requests used this billing cycle
|
||||
public let used: Int
|
||||
/// Request limit (e.g., 500 for legacy enterprise plans)
|
||||
public let limit: Int
|
||||
|
||||
public init(used: Int, limit: Int) {
|
||||
self.used = used
|
||||
self.limit = limit
|
||||
}
|
||||
|
||||
public var usedPercent: Double {
|
||||
guard self.limit > 0 else { return 0 }
|
||||
return (Double(self.used) / Double(self.limit)) * 100
|
||||
}
|
||||
|
||||
public var remainingPercent: Double {
|
||||
max(0, 100 - self.usedPercent)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user