Unified · Split
| @@ -1231,7 +1231,14 @@ extension UsageStore { · 1230 unmodified lines | |||
| 1231 | claudeCookieHeader: String, | 1231 | claudeCookieHeader: String, |
| 1232 | keepCLISessionsAlive: Bool) async -> String | 1232 | keepCLISessionsAlive: Bool) async -> String |
| 1233 | { | 1233 | { |
| 1234 | await self.runWithTimeout(seconds: 15) { | 1234 | struct OAuthDebugProbe: Sendable { |
| 1235 | let hasCredentials: Bool | ||
| 1236 | let ownerRawValue: String | ||
| 1237 | let sourceRawValue: String | ||
| 1238 | let isExpired: Bool | ||
| 1239 | } | ||
| 1240 | |||
| 1241 | return await self.runWithTimeout(seconds: 15) { | ||
| 1235 | var lines: [String] = [] | 1242 | var lines: [String] = [] |
| 1236 | let manualHeader = claudeCookieSource == .manual | 1243 | let manualHeader = claudeCookieSource == .manual |
| 1237 | ? CookieHeaderNormalizer.normalize(claudeCookieHeader) | 1244 | ? CookieHeaderNormalizer.normalize(claudeCookieHeader) |
| @@ -1241,12 +1248,20 @@ extension UsageStore { · 3 unmodified lines | |||
| 1241 | } else { | 1248 | } else { |
| 1242 | ClaudeWebAPIFetcher.hasSessionKey(browserDetection: self.browserDetection) { msg in lines.append(msg) } | 1249 | ClaudeWebAPIFetcher.hasSessionKey(browserDetection: self.browserDetection) { msg in lines.append(msg) } |
| 1243 | } | 1250 | } |
| 1244 | // Don't prompt for keychain access during debug dump | 1251 | // Run potentially blocking keychain probes off MainActor so debug dumps don't stall UI rendering. |
| 1245 | let oauthRecord = try? ClaudeOAuthCredentialsStore.loadRecord( | 1252 | let oauthProbe = await Task.detached(priority: .utility) { |
| 1246 | allowKeychainPrompt: false, | 1253 | // Don't prompt for keychain access during debug dump. |
| 1247 | respectKeychainPromptCooldown: true, | 1254 | let oauthRecord = try? ClaudeOAuthCredentialsStore.loadRecord( |
| 1248 | allowClaudeKeychainRepairWithoutPrompt: false) | 1255 | allowKeychainPrompt: false, |
| 1249 | let hasOAuthCredentials = oauthRecord?.credentials.scopes.contains("user:profile") == true | 1256 | respectKeychainPromptCooldown: true, |
| 1257 | allowClaudeKeychainRepairWithoutPrompt: false) | ||
| 1258 | return OAuthDebugProbe( | ||
| 1259 | hasCredentials: oauthRecord?.credentials.scopes.contains("user:profile") == true, | ||
| 1260 | ownerRawValue: oauthRecord?.owner.rawValue ?? "none", | ||
| 1261 | sourceRawValue: oauthRecord?.source.rawValue ?? "none", | ||
| 1262 | isExpired: oauthRecord?.credentials.isExpired ?? false) | ||
| 1263 | }.value | ||
| 1264 | let hasOAuthCredentials = oauthProbe.hasCredentials | ||
| 1250 | let hasClaudeBinary = ClaudeOAuthDelegatedRefreshCoordinator.isClaudeCLIAvailable() | 1265 | let hasClaudeBinary = ClaudeOAuthDelegatedRefreshCoordinator.isClaudeCLIAvailable() |
| 1251 | let delegatedCooldownSeconds = ClaudeOAuthDelegatedRefreshCoordinator.cooldownRemainingSeconds() | 1266 | let delegatedCooldownSeconds = ClaudeOAuthDelegatedRefreshCoordinator.cooldownRemainingSeconds() |
| 1252 | 1267 | ||
| @@ -1265,9 +1280,9 @@ extension UsageStore { · 12 unmodified lines | |||
| 1265 | } | 1280 | } |
| 1266 | lines.append("hasSessionKey=\(hasKey)") | 1281 | lines.append("hasSessionKey=\(hasKey)") |
| 1267 | lines.append("hasOAuthCredentials=\(hasOAuthCredentials)") | 1282 | lines.append("hasOAuthCredentials=\(hasOAuthCredentials)") |
| 1268 | lines.append("oauthCredentialOwner=\(oauthRecord?.owner.rawValue ?? "none")") | 1283 | lines.append("oauthCredentialOwner=\(oauthProbe.ownerRawValue)") |
| 1269 | lines.append("oauthCredentialSource=\(oauthRecord?.source.rawValue ?? "none")") | 1284 | lines.append("oauthCredentialSource=\(oauthProbe.sourceRawValue)") |
| 1270 | lines.append("oauthCredentialExpired=\(oauthRecord?.credentials.isExpired ?? false)") | 1285 | lines.append("oauthCredentialExpired=\(oauthProbe.isExpired)") |
| 1271 | lines.append("delegatedRefreshCLIAvailable=\(hasClaudeBinary)") | 1286 | lines.append("delegatedRefreshCLIAvailable=\(hasClaudeBinary)") |
| 1272 | lines.append("delegatedRefreshCooldownActive=\(delegatedCooldownSeconds != nil)") | 1287 | lines.append("delegatedRefreshCooldownActive=\(delegatedCooldownSeconds != nil)") |
| 1273 | if let delegatedCooldownSeconds { | 1288 | if let delegatedCooldownSeconds { |