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) } }