source dump of claude code
at main 120 lines 3.5 kB view raw
1import axios from 'axios' 2import { getOauthConfig } from 'src/constants/oauth.js' 3import { getOrganizationUUID } from 'src/services/oauth/client.js' 4import { getClaudeAIOAuthTokens } from '../auth.js' 5import { toError } from '../errors.js' 6import { logError } from '../log.js' 7import { getOAuthHeaders } from './api.js' 8 9export type EnvironmentKind = 'anthropic_cloud' | 'byoc' | 'bridge' 10export type EnvironmentState = 'active' 11 12export type EnvironmentResource = { 13 kind: EnvironmentKind 14 environment_id: string 15 name: string 16 created_at: string 17 state: EnvironmentState 18} 19 20export type EnvironmentListResponse = { 21 environments: EnvironmentResource[] 22 has_more: boolean 23 first_id: string | null 24 last_id: string | null 25} 26 27/** 28 * Fetches the list of available environments from the Environment API 29 * @returns Promise<EnvironmentResource[]> Array of available environments 30 * @throws Error if the API request fails or no access token is available 31 */ 32export async function fetchEnvironments(): Promise<EnvironmentResource[]> { 33 const accessToken = getClaudeAIOAuthTokens()?.accessToken 34 if (!accessToken) { 35 throw new Error( 36 'Claude Code web sessions require authentication with a Claude.ai account. API key authentication is not sufficient. Please run /login to authenticate, or check your authentication status with /status.', 37 ) 38 } 39 40 const orgUUID = await getOrganizationUUID() 41 if (!orgUUID) { 42 throw new Error('Unable to get organization UUID') 43 } 44 45 const url = `${getOauthConfig().BASE_API_URL}/v1/environment_providers` 46 47 try { 48 const headers = { 49 ...getOAuthHeaders(accessToken), 50 'x-organization-uuid': orgUUID, 51 } 52 53 const response = await axios.get<EnvironmentListResponse>(url, { 54 headers, 55 timeout: 15000, 56 }) 57 58 if (response.status !== 200) { 59 throw new Error( 60 `Failed to fetch environments: ${response.status} ${response.statusText}`, 61 ) 62 } 63 64 return response.data.environments 65 } catch (error) { 66 const err = toError(error) 67 logError(err) 68 throw new Error(`Failed to fetch environments: ${err.message}`) 69 } 70} 71 72/** 73 * Creates a default anthropic_cloud environment for users who have none. 74 * Uses the public environment_providers route (same auth as fetchEnvironments). 75 */ 76export async function createDefaultCloudEnvironment( 77 name: string, 78): Promise<EnvironmentResource> { 79 const accessToken = getClaudeAIOAuthTokens()?.accessToken 80 if (!accessToken) { 81 throw new Error('No access token available') 82 } 83 const orgUUID = await getOrganizationUUID() 84 if (!orgUUID) { 85 throw new Error('Unable to get organization UUID') 86 } 87 88 const url = `${getOauthConfig().BASE_API_URL}/v1/environment_providers/cloud/create` 89 const response = await axios.post<EnvironmentResource>( 90 url, 91 { 92 name, 93 kind: 'anthropic_cloud', 94 description: '', 95 config: { 96 environment_type: 'anthropic', 97 cwd: '/home/user', 98 init_script: null, 99 environment: {}, 100 languages: [ 101 { name: 'python', version: '3.11' }, 102 { name: 'node', version: '20' }, 103 ], 104 network_config: { 105 allowed_hosts: [], 106 allow_default_hosts: true, 107 }, 108 }, 109 }, 110 { 111 headers: { 112 ...getOAuthHeaders(accessToken), 113 'anthropic-beta': 'ccr-byoc-2025-07-29', 114 'x-organization-uuid': orgUUID, 115 }, 116 timeout: 15000, 117 }, 118 ) 119 return response.data 120}