Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
4.7 kB · 140 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141import { getSessionIngressToken, setSessionIngressToken,} from '../bootstrap/state.js'import { CCR_SESSION_INGRESS_TOKEN_PATH, maybePersistTokenForSubprocesses, readTokenFromWellKnownFile,} from './authFileDescriptor.js'import { logForDebugging } from './debug.js'import { errorMessage } from './errors.js'import { getFsImplementation } from './fsOperations.js'
/** * Read token via file descriptor, falling back to well-known file. * Uses global state to cache the result since file descriptors can only be read once. */function getTokenFromFileDescriptor(): string | null { // Check if we've already attempted to read the token const cachedToken = getSessionIngressToken() if (cachedToken !== undefined) { return cachedToken }
const fdEnv = process.env.CLAUDE_CODE_WEBSOCKET_AUTH_FILE_DESCRIPTOR if (!fdEnv) { // No FD env var — either we're not in CCR, or we're a subprocess whose // parent stripped the (useless) FD env var. Try the well-known file. const path = process.env.CLAUDE_SESSION_INGRESS_TOKEN_FILE ?? CCR_SESSION_INGRESS_TOKEN_PATH const fromFile = readTokenFromWellKnownFile(path, 'session ingress token') setSessionIngressToken(fromFile) return fromFile }
const fd = parseInt(fdEnv, 10) if (Number.isNaN(fd)) { logForDebugging( `CLAUDE_CODE_WEBSOCKET_AUTH_FILE_DESCRIPTOR must be a valid file descriptor number, got: ${fdEnv}`, { level: 'error' }, ) setSessionIngressToken(null) return null }
try { // Read from the file descriptor // Use /dev/fd on macOS/BSD, /proc/self/fd on Linux const fsOps = getFsImplementation() const fdPath = process.platform === 'darwin' || process.platform === 'freebsd' ? `/dev/fd/${fd}` : `/proc/self/fd/${fd}`
const token = fsOps.readFileSync(fdPath, { encoding: 'utf8' }).trim() if (!token) { logForDebugging('File descriptor contained empty token', { level: 'error', }) setSessionIngressToken(null) return null } logForDebugging(`Successfully read token from file descriptor ${fd}`) setSessionIngressToken(token) maybePersistTokenForSubprocesses( CCR_SESSION_INGRESS_TOKEN_PATH, token, 'session ingress token', ) return token } catch (error) { logForDebugging( `Failed to read token from file descriptor ${fd}: ${errorMessage(error)}`, { level: 'error' }, ) // FD env var was set but read failed — typically a subprocess that // inherited the env var but not the FD (ENXIO). Try the well-known file. const path = process.env.CLAUDE_SESSION_INGRESS_TOKEN_FILE ?? CCR_SESSION_INGRESS_TOKEN_PATH const fromFile = readTokenFromWellKnownFile(path, 'session ingress token') setSessionIngressToken(fromFile) return fromFile }}
/** * Get session ingress authentication token. * * Priority order: * 1. Environment variable (CLAUDE_CODE_SESSION_ACCESS_TOKEN) — set at spawn time, * updated in-process via updateSessionIngressAuthToken or * update_environment_variables stdin message from the parent bridge process. * 2. File descriptor (legacy path) — CLAUDE_CODE_WEBSOCKET_AUTH_FILE_DESCRIPTOR, * read once and cached. * 3. Well-known file — CLAUDE_SESSION_INGRESS_TOKEN_FILE env var path, or * /home/claude/.claude/remote/.session_ingress_token. Covers subprocesses * that can't inherit the FD. */export function getSessionIngressAuthToken(): string | null { // 1. Check environment variable const envToken = process.env.CLAUDE_CODE_SESSION_ACCESS_TOKEN if (envToken) { return envToken }
// 2. Check file descriptor (legacy path), with file fallback return getTokenFromFileDescriptor()}
/** * Build auth headers for the current session token. * Session keys (sk-ant-sid) use Cookie auth + X-Organization-Uuid; * JWTs use Bearer auth. */export function getSessionIngressAuthHeaders(): Record<string, string> { const token = getSessionIngressAuthToken() if (!token) return {} if (token.startsWith('sk-ant-sid')) { const headers: Record<string, string> = { Cookie: `sessionKey=${token}`, } const orgUuid = process.env.CLAUDE_CODE_ORGANIZATION_UUID if (orgUuid) { headers['X-Organization-Uuid'] = orgUuid } return headers } return { Authorization: `Bearer ${token}` }}
/** * Update the session ingress auth token in-process by setting the env var. * Used by the REPL bridge to inject a fresh token after reconnection * without restarting the process. */export function updateSessionIngressAuthToken(token: string): void { process.env.CLAUDE_CODE_SESSION_ACCESS_TOKEN = token}