Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
6.2 kB · 183 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184import memoize from 'lodash-es/memoize.js'import { homedir } from 'os'import { join } from 'path'
// Memoized: 150+ callers, many on hot paths. Keyed off CLAUDE_CONFIG_DIR so// tests that change the env var get a fresh value without explicit cache.clear.export const getClaudeConfigHomeDir = memoize( (): string => { return ( process.env.CLAUDE_CONFIG_DIR ?? join(homedir(), '.claude') ).normalize('NFC') }, () => process.env.CLAUDE_CONFIG_DIR,)
export function getTeamsDir(): string { return join(getClaudeConfigHomeDir(), 'teams')}
/** * Check if NODE_OPTIONS contains a specific flag. * Splits on whitespace and checks for exact match to avoid false positives. */export function hasNodeOption(flag: string): boolean { const nodeOptions = process.env.NODE_OPTIONS if (!nodeOptions) { return false } return nodeOptions.split(/\s+/).includes(flag)}
export function isEnvTruthy(envVar: string | boolean | undefined): boolean { if (!envVar) return false if (typeof envVar === 'boolean') return envVar const normalizedValue = envVar.toLowerCase().trim() return ['1', 'true', 'yes', 'on'].includes(normalizedValue)}
export function isEnvDefinedFalsy( envVar: string | boolean | undefined,): boolean { if (envVar === undefined) return false if (typeof envVar === 'boolean') return !envVar if (!envVar) return false const normalizedValue = envVar.toLowerCase().trim() return ['0', 'false', 'no', 'off'].includes(normalizedValue)}
/** * --bare / CLAUDE_CODE_SIMPLE — skip hooks, LSP, plugin sync, skill dir-walk, * attribution, background prefetches, and ALL keychain/credential reads. * Auth is strictly ANTHROPIC_API_KEY env or apiKeyHelper from --settings. * Explicit CLI flags (--plugin-dir, --add-dir, --mcp-config) still honored. * ~30 gates across the codebase. * * Checks argv directly (in addition to the env var) because several gates * run before main.tsx's action handler sets CLAUDE_CODE_SIMPLE=1 from --bare * — notably startKeychainPrefetch() at main.tsx top-level. */export function isBareMode(): boolean { return ( isEnvTruthy(process.env.CLAUDE_CODE_SIMPLE) || process.argv.includes('--bare') )}
/** * Parses an array of environment variable strings into a key-value object * @param envVars Array of strings in KEY=VALUE format * @returns Object with key-value pairs */export function parseEnvVars( rawEnvArgs: string[] | undefined,): Record<string, string> { const parsedEnv: Record<string, string> = {}
// Parse individual env vars if (rawEnvArgs) { for (const envStr of rawEnvArgs) { const [key, ...valueParts] = envStr.split('=') if (!key || valueParts.length === 0) { throw new Error( `Invalid environment variable format: ${envStr}, environment variables should be added as: -e KEY1=value1 -e KEY2=value2`, ) } parsedEnv[key] = valueParts.join('=') } } return parsedEnv}
/** * Get the AWS region with fallback to default * Matches the Anthropic Bedrock SDK's region behavior */export function getAWSRegion(): string { return process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || 'us-east-1'}
/** * Get the default Vertex AI region */export function getDefaultVertexRegion(): string { return process.env.CLOUD_ML_REGION || 'us-east5'}
/** * Check if bash commands should maintain project working directory (reset to original after each command) * @returns true if CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR is set to a truthy value */export function shouldMaintainProjectWorkingDir(): boolean { return isEnvTruthy(process.env.CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR)}
/** * Check if running on Homespace (ant-internal cloud environment) */export function isRunningOnHomespace(): boolean { return ( process.env.USER_TYPE === 'ant' && isEnvTruthy(process.env.COO_RUNNING_ON_HOMESPACE) )}
/** * Conservative check for whether Claude Code is running inside a protected * (privileged or ASL3+) COO namespace or cluster. * * Conservative means: when signals are ambiguous, assume protected. We would * rather over-report protected usage than miss it. Unprotected environments * are homespace, namespaces on the open allowlist, and no k8s/COO signals * at all (laptop/local dev). * * Used for telemetry to measure auto-mode usage in sensitive environments. */export function isInProtectedNamespace(): boolean { // USER_TYPE is build-time --define'd; in external builds this block is // DCE'd so the require() and namespace allowlist never appear in the bundle. if (process.env.USER_TYPE === 'ant') { /* eslint-disable @typescript-eslint/no-require-imports */ return ( require('./protectedNamespace.js') as typeof import('./protectedNamespace.js') ).checkProtectedNamespace() /* eslint-enable @typescript-eslint/no-require-imports */ } return false}
// @[MODEL LAUNCH]: Add a Vertex region override env var for the new model./** * Model prefix → env var for Vertex region overrides. * Order matters: more specific prefixes must come before less specific ones * (e.g., 'claude-opus-4-1' before 'claude-opus-4'). */const VERTEX_REGION_OVERRIDES: ReadonlyArray<[string, string]> = [ ['claude-haiku-4-5', 'VERTEX_REGION_CLAUDE_HAIKU_4_5'], ['claude-3-5-haiku', 'VERTEX_REGION_CLAUDE_3_5_HAIKU'], ['claude-3-5-sonnet', 'VERTEX_REGION_CLAUDE_3_5_SONNET'], ['claude-3-7-sonnet', 'VERTEX_REGION_CLAUDE_3_7_SONNET'], ['claude-opus-4-1', 'VERTEX_REGION_CLAUDE_4_1_OPUS'], ['claude-opus-4', 'VERTEX_REGION_CLAUDE_4_0_OPUS'], ['claude-sonnet-4-6', 'VERTEX_REGION_CLAUDE_4_6_SONNET'], ['claude-sonnet-4-5', 'VERTEX_REGION_CLAUDE_4_5_SONNET'], ['claude-sonnet-4', 'VERTEX_REGION_CLAUDE_4_0_SONNET'],]
/** * Get the Vertex AI region for a specific model. * Different models may be available in different regions. */export function getVertexRegionForModel( model: string | undefined,): string | undefined { if (model) { const match = VERTEX_REGION_OVERRIDES.find(([prefix]) => model.startsWith(prefix), ) if (match) { return process.env[match[1]] || getDefaultVertexRegion() } } return getDefaultVertexRegion()}