163 lines
5.8 KiB
Swift
163 lines
5.8 KiB
Swift
import CodexBarCore
|
|
import Foundation
|
|
|
|
extension SettingsStore {
|
|
var claudeUsageDataSource: ClaudeUsageDataSource {
|
|
get {
|
|
let source = self.configSnapshot.providerConfig(for: .claude)?.source
|
|
return Self.claudeUsageDataSource(from: source)
|
|
}
|
|
set {
|
|
let source: ProviderSourceMode? = switch newValue {
|
|
case .auto: .auto
|
|
case .api: .api
|
|
case .oauth: .oauth
|
|
case .web: .web
|
|
case .cli: .cli
|
|
}
|
|
self.updateProviderConfig(provider: .claude) { entry in
|
|
entry.source = source
|
|
}
|
|
self.logProviderModeChange(provider: .claude, field: "usageSource", value: newValue.rawValue)
|
|
if newValue != .cli {
|
|
self.claudeWebExtrasEnabled = false
|
|
}
|
|
}
|
|
}
|
|
|
|
var claudeCookieHeader: String {
|
|
get { self.configSnapshot.providerConfig(for: .claude)?.sanitizedCookieHeader ?? "" }
|
|
set {
|
|
self.updateProviderConfig(provider: .claude) { entry in
|
|
entry.cookieHeader = self.normalizedConfigValue(newValue)
|
|
}
|
|
self.logSecretUpdate(provider: .claude, field: "cookieHeader", value: newValue)
|
|
}
|
|
}
|
|
|
|
var claudeCookieSource: ProviderCookieSource {
|
|
get { self.resolvedCookieSource(provider: .claude, fallback: .auto) }
|
|
set {
|
|
self.updateProviderConfig(provider: .claude) { entry in
|
|
entry.cookieSource = newValue
|
|
}
|
|
self.logProviderModeChange(provider: .claude, field: "cookieSource", value: newValue.rawValue)
|
|
}
|
|
}
|
|
|
|
func ensureClaudeCookieLoaded() {}
|
|
|
|
var claudeAdminAPIKey: String {
|
|
get { self.configSnapshot.providerConfig(for: .claude)?.sanitizedAPIKey ?? "" }
|
|
set {
|
|
self.updateProviderConfig(provider: .claude) { entry in
|
|
entry.apiKey = self.normalizedConfigValue(newValue)
|
|
}
|
|
self.logSecretUpdate(provider: .claude, field: "apiKey", value: newValue)
|
|
}
|
|
}
|
|
|
|
var claudeSwapEnabled: Bool {
|
|
get { self.configSnapshot.providerConfig(for: .claude)?.claudeSwapEnabled ?? false }
|
|
set {
|
|
self.updateProviderConfig(provider: .claude) { entry in
|
|
entry.claudeSwapEnabled = newValue
|
|
}
|
|
self.logProviderModeChange(provider: .claude, field: "claudeSwapEnabled", value: String(newValue))
|
|
}
|
|
}
|
|
|
|
var claudeSwapExecutablePath: String {
|
|
get { self.configSnapshot.providerConfig(for: .claude)?.sanitizedClaudeSwapExecutablePath ?? "" }
|
|
set {
|
|
self.updateProviderConfig(provider: .claude) { entry in
|
|
entry.claudeSwapExecutablePath = self.normalizedConfigValue(newValue)
|
|
}
|
|
self.logProviderModeChange(
|
|
provider: .claude,
|
|
field: "claudeSwapExecutablePath",
|
|
value: newValue.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ? "cleared" : "set")
|
|
}
|
|
}
|
|
}
|
|
|
|
extension SettingsStore {
|
|
func claudeSettingsSnapshot(tokenOverride: TokenAccountOverride?) -> ProviderSettingsSnapshot
|
|
.ClaudeProviderSettings {
|
|
let account = self.selectedClaudeTokenAccount(tokenOverride: tokenOverride)
|
|
let routing = self.claudeCredentialRouting(account: account)
|
|
return ProviderSettingsSnapshot.ClaudeProviderSettings(
|
|
usageDataSource: self.claudeUsageDataSource,
|
|
webExtrasEnabled: self.claudeWebExtrasEnabled,
|
|
cookieSource: self.claudeSnapshotCookieSource(tokenOverride: tokenOverride, routing: routing),
|
|
manualCookieHeader: self.claudeSnapshotCookieHeader(
|
|
routing: routing,
|
|
hasSelectedAccount: account != nil),
|
|
organizationID: account?.sanitizedOrganizationID)
|
|
}
|
|
|
|
private static func claudeUsageDataSource(from source: ProviderSourceMode?) -> ClaudeUsageDataSource {
|
|
guard let source else { return .auto }
|
|
switch source {
|
|
case .auto, .api:
|
|
return source == .api ? .api : .auto
|
|
case .web:
|
|
return .web
|
|
case .cli:
|
|
return .cli
|
|
case .oauth:
|
|
return .oauth
|
|
}
|
|
}
|
|
|
|
private func claudeSnapshotCookieHeader(
|
|
routing: ClaudeCredentialRouting,
|
|
hasSelectedAccount: Bool) -> String
|
|
{
|
|
switch routing {
|
|
case .none:
|
|
hasSelectedAccount ? "" : self.claudeCookieHeader
|
|
case .oauth:
|
|
""
|
|
case .adminAPIKey:
|
|
""
|
|
case let .webCookie(header):
|
|
header
|
|
}
|
|
}
|
|
|
|
private func claudeSnapshotCookieSource(
|
|
tokenOverride: TokenAccountOverride?,
|
|
routing: ClaudeCredentialRouting) -> ProviderCookieSource
|
|
{
|
|
let fallback = self.claudeCookieSource
|
|
guard let support = TokenAccountSupportCatalog.support(for: .claude),
|
|
support.requiresManualCookieSource
|
|
else {
|
|
return fallback
|
|
}
|
|
if routing.isOAuth {
|
|
return .off
|
|
}
|
|
if routing.adminAPIKey != nil {
|
|
return .off
|
|
}
|
|
if self.tokenAccounts(for: .claude).isEmpty { return fallback }
|
|
return .manual
|
|
}
|
|
|
|
private func claudeCredentialRouting(account: ProviderTokenAccount?) -> ClaudeCredentialRouting {
|
|
let manualCookieHeader = account == nil ? self.claudeCookieHeader : nil
|
|
return ClaudeCredentialRouting.resolve(
|
|
tokenAccountToken: account?.token,
|
|
manualCookieHeader: manualCookieHeader)
|
|
}
|
|
|
|
private func selectedClaudeTokenAccount(tokenOverride: TokenAccountOverride?) -> ProviderTokenAccount? {
|
|
ProviderTokenAccountSelection.selectedAccount(
|
|
provider: .claude,
|
|
settings: self,
|
|
override: tokenOverride)
|
|
}
|
|
}
|