()
| 29 | let fired = false |
| 30 | |
| 31 | export function preconnectAnthropicApi(): void { |
| 32 | if (fired) return |
| 33 | fired = true |
| 34 | |
| 35 | // Skip if using a cloud provider — different endpoint + auth |
| 36 | if ( |
| 37 | isEnvTruthy(process.env.CLAUDE_CODE_USE_BEDROCK) || |
| 38 | isEnvTruthy(process.env.CLAUDE_CODE_USE_VERTEX) || |
| 39 | isEnvTruthy(process.env.CLAUDE_CODE_USE_FOUNDRY) |
| 40 | ) { |
| 41 | return |
| 42 | } |
| 43 | // Skip if proxy/mTLS/unix — SDK's custom dispatcher won't reuse this pool |
| 44 | if ( |
| 45 | process.env.HTTPS_PROXY || |
| 46 | process.env.https_proxy || |
| 47 | process.env.HTTP_PROXY || |
| 48 | process.env.http_proxy || |
| 49 | process.env.ANTHROPIC_UNIX_SOCKET || |
| 50 | process.env.CLAUDE_CODE_CLIENT_CERT || |
| 51 | process.env.CLAUDE_CODE_CLIENT_KEY |
| 52 | ) { |
| 53 | return |
| 54 | } |
| 55 | |
| 56 | // Use configured base URL (staging, local, or custom gateway). Covers |
| 57 | // ANTHROPIC_BASE_URL env + USE_STAGING_OAUTH + USE_LOCAL_OAUTH in one lookup. |
| 58 | // NODE_EXTRA_CA_CERTS no longer a skip — init.ts applied it before this fires. |
| 59 | const baseUrl = |
| 60 | process.env.ANTHROPIC_BASE_URL || getOauthConfig().BASE_API_URL |
| 61 | |
| 62 | // Fire and forget. HEAD means no response body — the connection is eligible |
| 63 | // for keep-alive pool reuse immediately after headers arrive. 10s timeout |
| 64 | // so a slow network doesn't hang the process; abort is fine since the real |
| 65 | // request will handshake fresh if needed. |
| 66 | // eslint-disable-next-line eslint-plugin-n/no-unsupported-features/node-builtins |
| 67 | void fetch(baseUrl, { |
| 68 | method: 'HEAD', |
| 69 | signal: AbortSignal.timeout(10_000), |
| 70 | }).catch(() => {}) |
| 71 | } |
| 72 |
no test coverage detected