* 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.
()
| 16 | * Uses global state to cache the result since file descriptors can only be read once. |
| 17 | */ |
| 18 | function getTokenFromFileDescriptor(): string | null { |
| 19 | // Check if we've already attempted to read the token |
| 20 | const cachedToken = getSessionIngressToken() |
| 21 | if (cachedToken !== undefined) { |
| 22 | return cachedToken |
| 23 | } |
| 24 | |
| 25 | const fdEnv = process.env.CLAUDE_CODE_WEBSOCKET_AUTH_FILE_DESCRIPTOR |
| 26 | if (!fdEnv) { |
| 27 | // No FD env var — either we're not in CCR, or we're a subprocess whose |
| 28 | // parent stripped the (useless) FD env var. Try the well-known file. |
| 29 | const path = |
| 30 | process.env.CLAUDE_SESSION_INGRESS_TOKEN_FILE ?? |
| 31 | CCR_SESSION_INGRESS_TOKEN_PATH |
| 32 | const fromFile = readTokenFromWellKnownFile(path, 'session ingress token') |
| 33 | setSessionIngressToken(fromFile) |
| 34 | return fromFile |
| 35 | } |
| 36 | |
| 37 | const fd = parseInt(fdEnv, 10) |
| 38 | if (Number.isNaN(fd)) { |
| 39 | logForDebugging( |
| 40 | `CLAUDE_CODE_WEBSOCKET_AUTH_FILE_DESCRIPTOR must be a valid file descriptor number, got: ${fdEnv}`, |
| 41 | { level: 'error' }, |
| 42 | ) |
| 43 | setSessionIngressToken(null) |
| 44 | return null |
| 45 | } |
| 46 | |
| 47 | try { |
| 48 | // Read from the file descriptor |
| 49 | // Use /dev/fd on macOS/BSD, /proc/self/fd on Linux |
| 50 | const fsOps = getFsImplementation() |
| 51 | const fdPath = |
| 52 | process.platform === 'darwin' || process.platform === 'freebsd' |
| 53 | ? `/dev/fd/${fd}` |
| 54 | : `/proc/self/fd/${fd}` |
| 55 | |
| 56 | const token = fsOps.readFileSync(fdPath, { encoding: 'utf8' }).trim() |
| 57 | if (!token) { |
| 58 | logForDebugging('File descriptor contained empty token', { |
| 59 | level: 'error', |
| 60 | }) |
| 61 | setSessionIngressToken(null) |
| 62 | return null |
| 63 | } |
| 64 | logForDebugging(`Successfully read token from file descriptor ${fd}`) |
| 65 | setSessionIngressToken(token) |
| 66 | maybePersistTokenForSubprocesses( |
| 67 | CCR_SESSION_INGRESS_TOKEN_PATH, |
| 68 | token, |
| 69 | 'session ingress token', |
| 70 | ) |
| 71 | return token |
| 72 | } catch (error) { |
| 73 | logForDebugging( |
| 74 | `Failed to read token from file descriptor ${fd}: ${errorMessage(error)}`, |
| 75 | { level: 'error' }, |
no test coverage detected