chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:22:33 +08:00
commit fc4fcbab58
1848 changed files with 472303 additions and 0 deletions
@@ -0,0 +1,92 @@
import Foundation
public enum DevinProviderDescriptor {
public static let descriptor: ProviderDescriptor = Self.makeDescriptor()
static func makeDescriptor() -> ProviderDescriptor {
ProviderDescriptor(
id: .devin,
metadata: ProviderMetadata(
id: .devin,
displayName: "Devin",
sessionLabel: "Daily",
weeklyLabel: "Weekly",
opusLabel: nil,
supportsOpus: false,
supportsCredits: false,
creditsHint: "",
toggleTitle: "Show Devin usage",
cliName: "devin",
defaultEnabled: false,
isPrimaryProvider: false,
usesAccountFallback: false,
browserCookieOrder: ProviderBrowserCookieDefaults.devinCookieImportOrder,
dashboardURL: "https://app.devin.ai",
subscriptionDashboardURL: "https://app.devin.ai/settings/usage",
statusPageURL: nil),
branding: ProviderBranding(
iconStyle: .devin,
iconResourceName: "ProviderIcon-devin",
color: ProviderColor(red: 70 / 255, green: 180 / 255, blue: 130 / 255)),
tokenCost: ProviderTokenCostConfig(
supportsTokenCost: false,
noDataMessage: { "Devin cost summary is not supported." }),
fetchPlan: ProviderFetchPlan(
sourceModes: [.auto, .web],
pipeline: ProviderFetchPipeline(resolveStrategies: { _ in [DevinWebFetchStrategy()] })),
cli: ProviderCLIConfig(
name: "devin",
versionDetector: nil))
}
}
struct DevinWebFetchStrategy: ProviderFetchStrategy {
let id: String = "devin.web"
let kind: ProviderFetchKind = .web
func isAvailable(_ context: ProviderFetchContext) async -> Bool {
let settings = context.settings?.devin
let source = settings?.cookieSource ?? .auto
guard source != .off else { return false }
if source == .manual {
return DevinUsageFetcher.manualAuth(from: Self.bearerTokenOverride(context: context)) != nil
}
#if os(macOS)
return true
#else
return false
#endif
}
func fetch(_ context: ProviderFetchContext) async throws -> ProviderFetchResult {
let fetcher = DevinUsageFetcher(browserDetection: context.browserDetection)
let settings = context.settings?.devin
let logger: ((String) -> Void)? = context.verbose
? { msg in CodexBarLog.logger(LogCategories.devin).verbose(msg) }
: nil
let snapshot = try await fetcher.fetch(
bearerTokenOverride: settings?.cookieSource == .manual ? Self.bearerTokenOverride(context: context) : nil,
organizationOverride: Self.organizationOverride(context: context),
timeout: context.webTimeout,
logger: logger)
return self.makeResult(
usage: snapshot.toUsageSnapshot(),
sourceLabel: "web")
}
func shouldFallback(on _: Error, context _: ProviderFetchContext) -> Bool {
false
}
private static func bearerTokenOverride(context: ProviderFetchContext) -> String? {
context.env["DEVIN_BEARER_TOKEN"]
?? context.env["DEVIN_AUTHORIZATION"]
?? context.settings?.devin?.manualBearerToken
}
private static func organizationOverride(context: ProviderFetchContext) -> String? {
context.env["DEVIN_ORGANIZATION"]
?? context.env["DEVIN_ORG"]
?? context.settings?.devin?.organization
}
}
@@ -0,0 +1,459 @@
import Foundation
#if os(macOS)
import SweetCookieKit
#endif
#if os(macOS)
enum DevinSessionImporter {
nonisolated(unsafe) static var importSessionOverrideForTesting:
((BrowserDetection, String?, ((String) -> Void)?) -> SessionInfo?)?
private static let storageOrigin = "https://app.devin.ai"
private static let externalOrgPrefix = "last-internal-org-for-external-org-v1-"
struct SessionInfo: Equatable {
let accessToken: String
let organization: String?
let internalOrganizationID: String?
let sourceLabel: String
}
struct LocalStorageCandidate {
let label: String
let url: URL
}
static func importSession(
browserDetection: BrowserDetection,
organizationOverride: String? = nil,
logger: ((String) -> Void)? = nil) -> SessionInfo?
{
if let override = self.importSessionOverrideForTesting {
return override(browserDetection, organizationOverride, logger)
}
let sessions = self.importSessions(
browserDetection: browserDetection,
organizationOverride: organizationOverride,
logger: logger)
return sessions.first
}
static func importSessions(
browserDetection: BrowserDetection,
organizationOverride: String? = nil,
logger: ((String) -> Void)? = nil) -> [SessionInfo]
{
if let override = self.importSessionOverrideForTesting {
return override(browserDetection, organizationOverride, logger).map { [$0] } ?? []
}
let log: (String) -> Void = { msg in logger?("[devin-storage] \(msg)") }
let candidates = self.chromeLocalStorageCandidates(browserDetection: browserDetection)
if !candidates.isEmpty {
log("Chrome local storage candidates: \(candidates.count)")
}
var sessions: [SessionInfo] = []
for candidate in candidates {
let storage = self.readLocalStorage(from: candidate.url, logger: log)
guard let session = self.session(
from: storage,
organizationOverride: organizationOverride,
sourceLabel: candidate.label)
else {
continue
}
log(
"Found Devin session in \(candidate.label); " +
"organization=\(session.organization != nil), internalOrganizationID=" +
"\(session.internalOrganizationID != nil)")
sessions.append(session)
}
sessions = self.rankSessions(self.deduplicateSessions(sessions))
if sessions.isEmpty {
log("No Devin session found in browser local storage")
}
return sessions
}
static func session(
from storage: [String: String],
organizationOverride: String? = nil,
sourceLabel: String) -> SessionInfo?
{
guard let accessToken = self.accessToken(from: storage) else {
return nil
}
let organizationInfo = self.organizationInfo(from: storage, organizationOverride: organizationOverride)
return SessionInfo(
accessToken: accessToken,
organization: organizationInfo.organization,
internalOrganizationID: organizationInfo.internalOrganizationID,
sourceLabel: sourceLabel)
}
static func accessToken(from storage: [String: String]) -> String? {
for (key, value) in storage where self.isAuth1StorageKey(key) {
guard let json = self.jsonObject(from: value),
let token = self.findAuth1Token(in: json)
else {
continue
}
return token
}
for (key, value) in storage where self.isAuth0StorageKey(key) {
guard let json = self.jsonObject(from: value),
let token = self.findAccessToken(in: json)
else {
continue
}
return token
}
for value in storage.values {
guard let json = self.jsonObject(from: value),
let token = self.findAccessToken(in: json)
else {
continue
}
return token
}
return nil
}
static func deduplicateSessions(_ sessions: [SessionInfo]) -> [SessionInfo] {
var order: [String] = []
var bestByToken: [String: SessionInfo] = [:]
for session in sessions {
if let existing = bestByToken[session.accessToken] {
if self.organizationScore(session) > self.organizationScore(existing) {
bestByToken[session.accessToken] = session
}
} else {
order.append(session.accessToken)
bestByToken[session.accessToken] = session
}
}
return order.compactMap { bestByToken[$0] }
}
static func rankSessions(_ sessions: [SessionInfo]) -> [SessionInfo] {
sessions.enumerated()
.sorted { lhs, rhs in
let lhsScore = self.organizationScore(lhs.element)
let rhsScore = self.organizationScore(rhs.element)
return lhsScore == rhsScore ? lhs.offset < rhs.offset : lhsScore > rhsScore
}
.map(\.element)
}
private static func organizationScore(_ session: SessionInfo) -> Int {
(session.organization == nil ? 0 : 1) + (session.internalOrganizationID == nil ? 0 : 2)
}
static func organizationInfo(
from storage: [String: String],
organizationOverride: String?) -> (organization: String?, internalOrganizationID: String?)
{
let override = DevinUsageFetcher.normalizedOrganization(organizationOverride)
let overrideSlug = override.flatMap(self.slug(fromNormalizedOrganization:))
var firstInternalOrgID: String?
for (key, value) in storage where self.isExternalOrgStorageKey(key) {
let suffix = self.externalOrgSlug(from: key)
let orgID = self.cleanedOrgID(value)
if firstInternalOrgID == nil {
firstInternalOrgID = orgID
}
if let overrideSlug, suffix == overrideSlug {
return (override, orgID)
}
if override == nil, suffix != "null" {
return ("org/\(suffix)", orgID)
}
}
if let inferred = self.inferredOrganizationInfo(from: storage, override: override) {
return inferred
}
if let override {
return (override, firstInternalOrgID ?? self.orgID(fromNormalizedOrganization: override))
}
return (firstInternalOrgID.map { "organizations/\($0)" }, firstInternalOrgID)
}
static func decodedStorageValue(_ value: String) -> String {
let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else { return trimmed }
if let data = trimmed.data(using: .utf8),
let decoded = try? JSONDecoder().decode(String.self, from: data)
{
return decoded.trimmingCharacters(in: .whitespacesAndNewlines)
}
return trimmed.trimmingCharacters(in: CharacterSet(charactersIn: "\""))
.trimmingCharacters(in: .whitespacesAndNewlines)
}
static func chromeLocalStorageCandidates(browserDetection: BrowserDetection) -> [LocalStorageCandidate] {
let installedBrowsers = self.localStorageBrowsers(browserDetection: browserDetection)
let roots = ChromiumProfileLocator
.roots(for: installedBrowsers, homeDirectories: BrowserCookieClient.defaultHomeDirectories())
.map { (url: $0.url, labelPrefix: $0.labelPrefix) }
var candidates: [LocalStorageCandidate] = []
for root in roots {
candidates.append(contentsOf: self.chromeProfileLocalStorageDirs(
root: root.url,
labelPrefix: root.labelPrefix))
}
return candidates
}
static func localStorageBrowsers(browserDetection: BrowserDetection) -> [Browser] {
let order = ProviderDefaults.metadata[.devin]?.browserCookieOrder ?? [.chrome]
return order.browsersWithProfileData(using: browserDetection)
}
private static func chromeProfileLocalStorageDirs(root: URL, labelPrefix: String) -> [LocalStorageCandidate] {
guard let entries = try? FileManager.default.contentsOfDirectory(
at: root,
includingPropertiesForKeys: [.isDirectoryKey],
options: [.skipsHiddenFiles])
else { return [] }
return entries.filter { url in
guard let isDir = (try? url.resourceValues(forKeys: [.isDirectoryKey]).isDirectory), isDir else {
return false
}
let name = url.lastPathComponent
return name == "Default" || name.hasPrefix("Profile ") || name.hasPrefix("user-")
}
.sorted { $0.lastPathComponent < $1.lastPathComponent }
.compactMap { dir in
let levelDBURL = dir.appendingPathComponent("Local Storage").appendingPathComponent("leveldb")
guard FileManager.default.fileExists(atPath: levelDBURL.path) else { return nil }
return LocalStorageCandidate(label: "\(labelPrefix) \(dir.lastPathComponent)", url: levelDBURL)
}
}
private static func readLocalStorage(from levelDBURL: URL, logger: ((String) -> Void)?) -> [String: String] {
var storage: [String: String] = [:]
let entries = SweetCookieKit.ChromiumLocalStorageReader.readEntries(
for: self.storageOrigin,
in: levelDBURL,
logger: logger)
for entry in entries {
storage[entry.key] = self.decodedStorageValue(entry.value)
}
let textEntries = SweetCookieKit.ChromiumLocalStorageReader.readTextEntries(
in: levelDBURL,
logger: logger)
for entry in textEntries where storage[entry.key] == nil {
if self.isUsefulStorageKey(entry.key) {
storage[entry.key] = self.decodedStorageValue(entry.value)
}
}
return storage
}
private static func jsonObject(from raw: String) -> Any? {
guard let data = raw.data(using: .utf8) else { return nil }
return try? JSONSerialization.jsonObject(with: data)
}
private static func findAuth1Token(in object: Any) -> String? {
guard let dictionary = object as? [String: Any],
let token = dictionary["token"] as? String
else {
return nil
}
let value = token.trimmingCharacters(in: .whitespacesAndNewlines)
return value.hasPrefix("auth1_") && value.count > 20 ? value : nil
}
private static func findAccessToken(in object: Any) -> String? {
if let dictionary = object as? [String: Any] {
for key in ["access_token", "accessToken"] {
if let value = dictionary[key] as? String,
self.looksLikeToken(value)
{
return value
}
}
for value in dictionary.values {
if let found = self.findAccessToken(in: value) {
return found
}
}
}
if let array = object as? [Any] {
for value in array {
if let found = self.findAccessToken(in: value) {
return found
}
}
}
return nil
}
private static func looksLikeToken(_ raw: String) -> Bool {
let value = raw.trimmingCharacters(in: .whitespacesAndNewlines)
return value.count > 20 && (value.hasPrefix("eyJ") || value.contains("."))
}
private static func isAuth1StorageKey(_ key: String) -> Bool {
key.hasSuffix("auth1_session")
}
private static func isAuth0StorageKey(_ key: String) -> Bool {
key.contains("auth0spajs@@::")
}
private static func isExternalOrgStorageKey(_ key: String) -> Bool {
key.contains(self.externalOrgPrefix)
}
private static func isUsefulStorageKey(_ key: String) -> Bool {
self.isAuth1StorageKey(key) ||
self.isAuth0StorageKey(key) ||
self.isExternalOrgStorageKey(key) ||
key.contains("post-auth-v") ||
key.contains("member-info-v") ||
key.contains("feature-flags-cache:org-") ||
key.contains("feature-flags-cache:org_")
}
private static func inferredOrganizationInfo(
from storage: [String: String],
override: String?) -> (organization: String?, internalOrganizationID: String?)?
{
let overrideSlug = override.flatMap(self.slug(fromNormalizedOrganization:))
let overrideOrgID = override.flatMap(self.orgID(fromNormalizedOrganization:))
var fallbackSlug: String?
var fallbackInternalOrgID: String?
for (key, value) in storage {
let object = self.jsonObject(from: value)
let internalOrgID = self.cleanedOrgID(self.firstString(
in: object,
matching: ["internalOrgId", "internal_org_id", "org_id", "orgId"]))
?? self.internalOrgIDFromStorageKey(key)
let slug = self.cleanedSlug(
self.slugFromPostAuthKey(key) ??
self.firstString(in: object, matching: ["orgName", "org_name", "externalOrgId", "external_org_id"]))
if let overrideOrgID, internalOrgID == overrideOrgID {
return (override, internalOrgID)
}
if let overrideSlug, slug == overrideSlug {
return (override, internalOrgID)
}
if fallbackSlug == nil, let slug {
fallbackSlug = slug
}
if fallbackInternalOrgID == nil, let internalOrgID {
fallbackInternalOrgID = internalOrgID
}
}
if let override, fallbackInternalOrgID != nil {
return (override, fallbackInternalOrgID)
}
if let fallbackSlug {
return ("org/\(fallbackSlug)", fallbackInternalOrgID)
}
if let fallbackInternalOrgID {
return ("organizations/\(fallbackInternalOrgID)", fallbackInternalOrgID)
}
return nil
}
private static func externalOrgSlug(from key: String) -> String {
guard let range = key.range(of: self.externalOrgPrefix) else { return key }
return String(key[range.upperBound...])
}
private static func cleanedOrgID(_ raw: String) -> String? {
let value = self.decodedStorageValue(raw)
guard DevinUsageFetcher.isInternalOrganizationID(value) else { return nil }
return value
}
private static func cleanedOrgID(_ raw: String?) -> String? {
guard let raw else { return nil }
return self.cleanedOrgID(raw)
}
private static func cleanedSlug(_ raw: String?) -> String? {
guard let raw else { return nil }
let value = self.decodedStorageValue(raw)
.trimmingCharacters(in: CharacterSet(charactersIn: "/"))
.trimmingCharacters(in: .whitespacesAndNewlines)
guard !value.isEmpty, value != "null", !DevinUsageFetcher.isInternalOrganizationID(value) else {
return nil
}
if value.hasPrefix("org/") {
return String(value.dropFirst(4))
}
return value
}
private static func slugFromPostAuthKey(_ key: String) -> String? {
guard let range = key.range(of: "-org_name-") else { return nil }
return String(key[range.upperBound...])
}
private static func internalOrgIDFromStorageKey(_ key: String) -> String? {
guard let range = key.range(of: #"org[-_][A-Za-z0-9]{8,}"#, options: .regularExpression) else {
return nil
}
return self.cleanedOrgID(String(key[range]))
}
private static func firstString(in object: Any?, matching keys: Set<String>) -> String? {
if let dictionary = object as? [String: Any] {
for (key, value) in dictionary {
if keys.contains(key), let string = value as? String, !string.isEmpty {
return string
}
if let found = self.firstString(in: value, matching: keys) {
return found
}
}
}
if let array = object as? [Any] {
for value in array {
if let found = self.firstString(in: value, matching: keys) {
return found
}
}
}
return nil
}
private static func slug(fromNormalizedOrganization organization: String) -> String? {
guard organization.hasPrefix("org/") else { return nil }
return String(organization.dropFirst(4))
}
private static func orgID(fromNormalizedOrganization organization: String) -> String? {
guard organization.hasPrefix("organizations/") else { return nil }
return String(organization.dropFirst("organizations/".count))
}
}
#endif
@@ -0,0 +1,271 @@
import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif
public struct DevinUsageFetcher: Sendable {
private static let log = CodexBarLog.logger(LogCategories.devin)
private static let baseURL = URL(string: "https://app.devin.ai")!
private static let defaultUserAgent =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) " +
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36"
public struct RequestAuth: Sendable, Equatable {
public let bearerToken: String
public let organization: String?
public let internalOrganizationID: String?
public let sourceLabel: String
public init(
bearerToken: String,
organization: String?,
internalOrganizationID: String?,
sourceLabel: String)
{
self.bearerToken = bearerToken
self.organization = organization
self.internalOrganizationID = internalOrganizationID
self.sourceLabel = sourceLabel
}
}
public let browserDetection: BrowserDetection
public init(browserDetection: BrowserDetection) {
self.browserDetection = browserDetection
}
public func fetch(
bearerTokenOverride: String? = nil,
organizationOverride: String? = nil,
timeout: TimeInterval = 15,
logger: ((String) -> Void)? = nil,
now: Date = Date(),
transport: any ProviderHTTPTransport = ProviderHTTPClient.shared) async throws -> DevinUsageSnapshot
{
let auths = try self.resolveAuths(
bearerTokenOverride: bearerTokenOverride,
organizationOverride: organizationOverride,
logger: logger)
var lastError: Error?
for auth in auths {
do {
return try await Self.fetchQuotaUsage(
auth: auth,
organizationOverride: organizationOverride,
timeout: timeout,
logger: logger,
now: now,
transport: transport)
} catch {
lastError = error
logger?("[devin] Session from \(auth.sourceLabel) failed: \(error.localizedDescription)")
if auth.sourceLabel == "manual" || !Self.shouldTryNextSession(after: error) {
throw error
}
}
}
throw lastError ?? DevinUsageError.noSession
}
public static func fetchQuotaUsage(
auth: RequestAuth,
organizationOverride: String? = nil,
timeout: TimeInterval = 15,
logger: ((String) -> Void)? = nil,
now: Date = Date(),
transport: any ProviderHTTPTransport = ProviderHTTPClient.shared) async throws -> DevinUsageSnapshot
{
let organization = self.normalizedOrganization(organizationOverride) ??
self.normalizedOrganization(auth.organization)
guard let organization else {
throw DevinUsageError.missingOrganization
}
var lastError: Error?
for path in self.candidatePaths(
organization: organization,
internalOrganizationID: auth.internalOrganizationID)
{
let data: Data
do {
data = try await self.fetch(
path: path,
auth: auth,
timeout: timeout,
transport: transport)
} catch {
lastError = error
logger?("[devin] /api/\(path) failed: \(error.localizedDescription)")
if case DevinUsageError.invalidCredentials = error {
throw error
}
continue
}
logger?("[devin] Fetched quota usage from /api/\(path)")
return try DevinUsageParser.parse(data, organization: organization, now: now)
}
throw lastError ?? DevinUsageError.apiError("No Devin quota endpoint succeeded.")
}
public static func manualAuth(from raw: String?, organization: String? = nil) -> RequestAuth? {
guard var token = raw?.trimmingCharacters(in: .whitespacesAndNewlines), !token.isEmpty else {
return nil
}
if token.lowercased().hasPrefix("authorization:") {
token = token.dropHeaderName().trimmingCharacters(in: .whitespacesAndNewlines)
}
if token.lowercased().hasPrefix("bearer ") {
token = String(token.dropFirst(7)).trimmingCharacters(in: .whitespacesAndNewlines)
}
guard !token.isEmpty else { return nil }
return RequestAuth(
bearerToken: token,
organization: self.normalizedOrganization(organization),
internalOrganizationID: self.internalOrganizationID(from: organization),
sourceLabel: "manual")
}
private func resolveAuths(
bearerTokenOverride: String?,
organizationOverride: String?,
logger: ((String) -> Void)?) throws -> [RequestAuth]
{
if let manual = Self.manualAuth(from: bearerTokenOverride, organization: organizationOverride) {
logger?("[devin] Using manual Bearer token")
return [manual]
}
#if os(macOS)
let normalizedOrganizationOverride = Self.normalizedOrganization(organizationOverride)
let sessions = DevinSessionImporter.importSessions(
browserDetection: self.browserDetection,
organizationOverride: normalizedOrganizationOverride,
logger: logger)
guard !sessions.isEmpty else {
throw DevinUsageError.noSession
}
logger?("[devin] Found \(sessions.count) browser session(s)")
return sessions.map { session in
RequestAuth(
bearerToken: session.accessToken,
organization: normalizedOrganizationOverride ?? Self.normalizedOrganization(session.organization),
internalOrganizationID: session.internalOrganizationID,
sourceLabel: session.sourceLabel)
}
#else
throw DevinUsageError.noSession
#endif
}
static func shouldTryNextSession(after error: Error) -> Bool {
switch error {
case DevinUsageError.invalidCredentials, DevinUsageError.apiError, DevinUsageError.missingOrganization:
true
default:
false
}
}
private static func fetch(
path: String,
auth: RequestAuth,
timeout: TimeInterval,
transport: any ProviderHTTPTransport) async throws -> Data
{
let url = self.baseURL.appending(path: "api/\(path)")
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.timeoutInterval = timeout
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("en-US,en;q=0.9", forHTTPHeaderField: "Accept-Language")
request.setValue(self.defaultUserAgent, forHTTPHeaderField: "User-Agent")
request.setValue("Bearer \(auth.bearerToken)", forHTTPHeaderField: "Authorization")
if let internalOrganizationID = auth.internalOrganizationID {
request.setValue(internalOrganizationID, forHTTPHeaderField: "x-cog-org-id")
}
let response = try await transport.response(for: request)
guard response.statusCode == 200 else {
let body = String(data: response.data.prefix(200), encoding: .utf8) ?? "<binary>"
if response.statusCode == 401 || response.statusCode == 403 {
throw DevinUsageError.invalidCredentials
}
Self.log.error("Devin API returned \(response.statusCode): \(body)")
throw DevinUsageError.apiError("HTTP \(response.statusCode)")
}
return response.data
}
private static func candidatePaths(organization: String, internalOrganizationID: String?) -> [String] {
var paths: [String] = []
let normalized = self.normalizedOrganization(organization) ?? organization
if let internalOrganizationID {
paths.append("\(internalOrganizationID)/billing/quota/usage")
}
paths.append("\(normalized)/billing/quota/usage")
if normalized.hasPrefix("org/") {
let slug = String(normalized.dropFirst(4))
paths.append("\(slug)/billing/quota/usage")
}
if !normalized.hasPrefix("org/"), !normalized.hasPrefix("organizations/") {
paths.append("org/\(normalized)/billing/quota/usage")
}
if let internalOrganizationID {
paths.append("organizations/\(internalOrganizationID)/billing/quota/usage")
}
return paths.removingDuplicates()
}
public static func normalizedOrganization(_ raw: String?) -> String? {
guard var value = raw?.trimmingCharacters(in: .whitespacesAndNewlines), !value.isEmpty else {
return nil
}
if let url = URL(string: value),
let host = url.host?.lowercased(),
host == "devin.ai" || host.hasSuffix(".devin.ai")
{
let components = url.path.split(separator: "/").map(String.init)
if components.count >= 2, components[0] == "org" {
value = "org/\(components[1])"
} else if components.count >= 2, components[0] == "organizations" {
value = "organizations/\(components[1])"
}
}
value = value.trimmingCharacters(in: CharacterSet(charactersIn: "/"))
if value.hasPrefix("org/") || value.hasPrefix("organizations/") {
return value
}
if self.isInternalOrganizationID(value) {
return "organizations/\(value)"
}
return "org/\(value)"
}
private static func internalOrganizationID(from raw: String?) -> String? {
guard let normalized = self.normalizedOrganization(raw),
normalized.hasPrefix("organizations/")
else {
return nil
}
return String(normalized.dropFirst("organizations/".count))
}
static func isInternalOrganizationID(_ value: String) -> Bool {
value.hasPrefix("org-") || value.hasPrefix("org_")
}
}
extension String {
fileprivate func dropHeaderName() -> String {
guard let index = self.firstIndex(of: ":") else { return self }
return String(self[self.index(after: index)...])
}
}
extension [String] {
fileprivate func removingDuplicates() -> [String] {
var seen = Set<String>()
return self.filter { seen.insert($0).inserted }
}
}
@@ -0,0 +1,345 @@
import CoreFoundation
import Foundation
public enum DevinUsageError: LocalizedError, Sendable {
case noSession
case missingOrganization
case invalidCredentials
case apiError(String)
case parseFailed(String)
public var errorDescription: String? {
switch self {
case .noSession:
"No Devin browser session found. Please log in to app.devin.ai or paste a Bearer token."
case .missingOrganization:
"No Devin organization was found. Open an app.devin.ai/org/... page " +
"or set the organization in Devin settings."
case .invalidCredentials:
"Devin session token is invalid or expired."
case let .apiError(message):
"Devin API error: \(message)"
case let .parseFailed(message):
"Could not parse Devin usage: \(message)"
}
}
}
public struct DevinQuotaWindow: Sendable, Equatable {
public let usedPercent: Double
public let resetsAt: Date?
public init(usedPercent: Double, resetsAt: Date? = nil) {
self.usedPercent = min(100, max(0, usedPercent))
self.resetsAt = resetsAt
}
}
public struct DevinUsageSnapshot: Sendable, Equatable {
public let daily: DevinQuotaWindow?
public let weekly: DevinQuotaWindow?
public let planName: String?
public let organization: String?
public let updatedAt: Date
public let overageBalance: Double?
public init(
daily: DevinQuotaWindow?,
weekly: DevinQuotaWindow?,
planName: String?,
organization: String?,
updatedAt: Date,
overageBalance: Double? = nil)
{
self.daily = daily
self.weekly = weekly
self.planName = planName
self.organization = organization
self.updatedAt = updatedAt
self.overageBalance = overageBalance
}
public func toUsageSnapshot() -> UsageSnapshot {
let primary = self.daily.map {
RateWindow(
usedPercent: $0.usedPercent,
windowMinutes: 24 * 60,
resetsAt: $0.resetsAt,
resetDescription: "Daily")
}
let secondary = self.weekly.map {
RateWindow(
usedPercent: $0.usedPercent,
windowMinutes: 7 * 24 * 60,
resetsAt: $0.resetsAt,
resetDescription: "Weekly")
}
let identity = ProviderIdentitySnapshot(
providerID: .devin,
accountEmail: nil,
accountOrganization: self.organization,
loginMethod: self.planName)
let providerCost: ProviderCostSnapshot? = self.overageBalance.map {
ProviderCostSnapshot(
used: $0,
limit: 0,
currencyCode: "USD",
period: "Extra usage balance",
updatedAt: self.updatedAt)
}
return UsageSnapshot(
primary: primary,
secondary: secondary,
providerCost: providerCost,
updatedAt: self.updatedAt,
identity: identity)
}
}
public enum DevinUsageParser {
public static func parse(_ data: Data, organization: String?, now: Date = Date()) throws -> DevinUsageSnapshot {
let object = try JSONSerialization.jsonObject(with: data)
return try self.parse(object, organization: organization, now: now)
}
public static func parse(_ object: Any, organization: String?, now: Date = Date()) throws -> DevinUsageSnapshot {
let current = (object as? [String: Any]).map(self.currentQuotaWindows)
let daily = current?.daily ?? self.findWindow(in: object, matching: self.isDailyKey)
let weekly = current?.weekly ?? self.findWindow(in: object, matching: self.isWeeklyKey)
guard daily != nil || weekly != nil else {
throw DevinUsageError.parseFailed("Missing Devin quota windows.")
}
return DevinUsageSnapshot(
daily: daily,
weekly: weekly,
planName: self.findPlanName(in: object),
organization: self.displayOrganization(from: organization),
updatedAt: now,
overageBalance: self.findOverageBalance(in: object))
}
private static func findOverageBalance(in object: Any) -> Double? {
guard let dictionary = object as? [String: Any] else { return nil }
if let value = self.nonnegativeFiniteDouble(dictionary["overage_balance"]) { return value }
if let cents = self.nonnegativeFiniteDouble(dictionary["overage_balance_cents"]) { return cents / 100.0 }
return nil
}
private static func nonnegativeFiniteDouble(_ value: Any?) -> Double? {
guard let value = self.double(value), value.isFinite, value >= 0 else { return nil }
return value
}
private static func currentQuotaWindows(_ dictionary: [String: Any])
-> (daily: DevinQuotaWindow?, weekly: DevinQuotaWindow?)
{
let daily = self.currentQuotaWindow(
percent: dictionary["daily_percentage"],
resetsAt: dictionary["daily_reset_at"])
let weekly = self.currentQuotaWindow(
percent: dictionary["weekly_percentage"],
resetsAt: dictionary["weekly_reset_at"])
return (daily, weekly)
}
private static func currentQuotaWindow(percent: Any?, resetsAt: Any?) -> DevinQuotaWindow? {
guard let usedPercent = self.double(percent) else { return nil }
return DevinQuotaWindow(
usedPercent: usedPercent < 1 ? usedPercent * 100 : usedPercent,
resetsAt: self.date(from: resetsAt))
}
private static func findWindow(in object: Any, matching keyMatches: (String) -> Bool) -> DevinQuotaWindow? {
if let dictionary = object as? [String: Any] {
for (key, value) in dictionary where keyMatches(key) {
if let window = self.window(from: value) {
return window
}
}
for value in dictionary.values {
if let found = self.findWindow(in: value, matching: keyMatches) {
return found
}
}
}
if let array = object as? [Any] {
for value in array {
if let found = self.findWindow(in: value, matching: keyMatches) {
return found
}
}
}
return nil
}
private static func window(from object: Any) -> DevinQuotaWindow? {
guard let dictionary = object as? [String: Any] else {
guard let percent = self.percent(from: object) else { return nil }
return DevinQuotaWindow(usedPercent: percent, resetsAt: nil)
}
if let percent = self.percent(from: dictionary) {
return DevinQuotaWindow(
usedPercent: percent,
resetsAt: self.findResetDate(in: dictionary))
}
if let nested = dictionary.values.lazy.compactMap({ self.window(from: $0) }).first {
return nested
}
return nil
}
private static func percent(from object: Any) -> Double? {
if let number = self.double(object) {
return number <= 1 ? number * 100 : number
}
guard let dictionary = object as? [String: Any] else { return nil }
let directKeys = [
"used_percent",
"usedPercent",
"usage_percent",
"usagePercent",
"percent_used",
"percentUsed",
"percent",
]
for key in directKeys {
if let value = self.double(dictionary[key]) {
return value <= 1 ? value * 100 : value
}
}
let remainingKeys = ["remaining_percent", "remainingPercent", "percent_remaining", "percentRemaining"]
for key in remainingKeys {
if let value = self.double(dictionary[key]) {
let percent = value <= 1 ? value * 100 : value
return 100 - percent
}
}
let used = self.firstDouble(in: dictionary, keys: ["used", "usage", "used_count", "usedCount", "consumed"])
let limit = self.firstDouble(in: dictionary, keys: ["limit", "quota", "total", "max", "available"])
if let used, let limit, limit > 0 {
return used / limit * 100
}
let remaining = self.firstDouble(in: dictionary, keys: ["remaining", "left", "available"])
if let remaining, let limit, limit > 0 {
return (limit - remaining) / limit * 100
}
return nil
}
private static func findPlanName(in object: Any) -> String? {
if let dictionary = object as? [String: Any] {
for key in ["plan_name", "planName", "plan", "tier", "subscription_tier", "subscriptionTier"] {
if let value = dictionary[key] as? String,
let cleaned = self.cleanDisplay(value)
{
return cleaned
}
}
for value in dictionary.values {
if let found = self.findPlanName(in: value) {
return found
}
}
}
if let array = object as? [Any] {
for value in array {
if let found = self.findPlanName(in: value) {
return found
}
}
}
return nil
}
private static func findResetDate(in dictionary: [String: Any]) -> Date? {
for (key, value) in dictionary where key.localizedCaseInsensitiveContains("reset") {
if let date = self.date(from: value) {
return date
}
}
return nil
}
private static func date(from value: Any?) -> Date? {
if let raw = value as? String {
if let date = ISO8601DateFormatter().date(from: raw) {
return date
}
if let number = Double(raw) {
return self.date(from: number)
}
}
if let number = self.double(value) {
return self.date(from: number)
}
return nil
}
private static func date(from number: Double) -> Date? {
guard number > 0 else { return nil }
let seconds = number > 10_000_000_000 ? number / 1000 : number
return Date(timeIntervalSince1970: seconds)
}
private static func firstDouble(in dictionary: [String: Any], keys: [String]) -> Double? {
for key in keys {
if let value = self.double(dictionary[key]) {
return value
}
}
return nil
}
private static func double(_ value: Any?) -> Double? {
switch value {
case let number as NSNumber:
CFGetTypeID(number) == CFBooleanGetTypeID() ? nil : number.doubleValue
case let string as String:
Double(string.trimmingCharacters(in: .whitespacesAndNewlines))
default:
nil
}
}
private static func isDailyKey(_ raw: String) -> Bool {
let key = raw.lowercased()
return !key.contains("hide") && (key.contains("daily") || key.contains("day"))
}
private static func isWeeklyKey(_ raw: String) -> Bool {
let key = raw.lowercased()
return !key.contains("hide") && (key.contains("weekly") || key.contains("week"))
}
private static func displayOrganization(from raw: String?) -> String? {
guard let raw = raw?.trimmingCharacters(in: .whitespacesAndNewlines), !raw.isEmpty else { return nil }
if raw.hasPrefix("org/") {
return String(raw.dropFirst(4))
}
if raw.hasPrefix("organizations/") {
return String(raw.dropFirst("organizations/".count))
}
return raw
}
private static func cleanDisplay(_ raw: String) -> String? {
let cleaned = raw.trimmingCharacters(in: .whitespacesAndNewlines)
guard !cleaned.isEmpty else { return nil }
return cleaned.split(separator: "_").flatMap { $0.split(separator: "-") }.map { part in
part.prefix(1).uppercased() + String(part.dropFirst())
}.joined(separator: " ")
}
}