source dump of claude code
at main 118 lines 4.0 kB view raw
1import { 2 checkAdminRequestEligibility, 3 createAdminRequest, 4 getMyAdminRequests, 5} from '../../services/api/adminRequests.js' 6import { invalidateOverageCreditGrantCache } from '../../services/api/overageCreditGrant.js' 7import { type ExtraUsage, fetchUtilization } from '../../services/api/usage.js' 8import { getSubscriptionType } from '../../utils/auth.js' 9import { hasClaudeAiBillingAccess } from '../../utils/billing.js' 10import { openBrowser } from '../../utils/browser.js' 11import { getGlobalConfig, saveGlobalConfig } from '../../utils/config.js' 12import { logError } from '../../utils/log.js' 13 14type ExtraUsageResult = 15 | { type: 'message'; value: string } 16 | { type: 'browser-opened'; url: string; opened: boolean } 17 18export async function runExtraUsage(): Promise<ExtraUsageResult> { 19 if (!getGlobalConfig().hasVisitedExtraUsage) { 20 saveGlobalConfig(prev => ({ ...prev, hasVisitedExtraUsage: true })) 21 } 22 // Invalidate only the current org's entry so a follow-up read refetches 23 // the granted state. Separate from the visited flag since users may run 24 // /extra-usage more than once while iterating on the claim flow. 25 invalidateOverageCreditGrantCache() 26 27 const subscriptionType = getSubscriptionType() 28 const isTeamOrEnterprise = 29 subscriptionType === 'team' || subscriptionType === 'enterprise' 30 const hasBillingAccess = hasClaudeAiBillingAccess() 31 32 if (!hasBillingAccess && isTeamOrEnterprise) { 33 // Mirror apps/claude-ai useHasUnlimitedOverage(): if overage is enabled 34 // with no monthly cap, there is nothing to request. On fetch error, fall 35 // through and let the user ask (matching web's "err toward show" behavior). 36 let extraUsage: ExtraUsage | null | undefined 37 try { 38 const utilization = await fetchUtilization() 39 extraUsage = utilization?.extra_usage 40 } catch (error) { 41 logError(error as Error) 42 } 43 44 if (extraUsage?.is_enabled && extraUsage.monthly_limit === null) { 45 return { 46 type: 'message', 47 value: 48 'Your organization already has unlimited extra usage. No request needed.', 49 } 50 } 51 52 try { 53 const eligibility = await checkAdminRequestEligibility('limit_increase') 54 if (eligibility?.is_allowed === false) { 55 return { 56 type: 'message', 57 value: 'Please contact your admin to manage extra usage settings.', 58 } 59 } 60 } catch (error) { 61 logError(error as Error) 62 // If eligibility check fails, continue — the create endpoint will enforce if necessary 63 } 64 65 try { 66 const pendingOrDismissedRequests = await getMyAdminRequests( 67 'limit_increase', 68 ['pending', 'dismissed'], 69 ) 70 if (pendingOrDismissedRequests && pendingOrDismissedRequests.length > 0) { 71 return { 72 type: 'message', 73 value: 74 'You have already submitted a request for extra usage to your admin.', 75 } 76 } 77 } catch (error) { 78 logError(error as Error) 79 // Fall through to creating a new request below 80 } 81 82 try { 83 await createAdminRequest({ 84 request_type: 'limit_increase', 85 details: null, 86 }) 87 return { 88 type: 'message', 89 value: extraUsage?.is_enabled 90 ? 'Request sent to your admin to increase extra usage.' 91 : 'Request sent to your admin to enable extra usage.', 92 } 93 } catch (error) { 94 logError(error as Error) 95 // Fall through to generic message below 96 } 97 98 return { 99 type: 'message', 100 value: 'Please contact your admin to manage extra usage settings.', 101 } 102 } 103 104 const url = isTeamOrEnterprise 105 ? 'https://claude.ai/admin-settings/usage' 106 : 'https://claude.ai/settings/usage' 107 108 try { 109 const opened = await openBrowser(url) 110 return { type: 'browser-opened', url, opened } 111 } catch (error) { 112 logError(error as Error) 113 return { 114 type: 'message', 115 value: `Failed to open browser. Please visit ${url} to manage extra usage.`, 116 } 117 } 118}