* 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.
()
| 123 | * Uses global state to cache the result since file descriptors can only be read once. |
| 124 | */ |
| 125 | function getTokenFromFileDescriptor(): string | null { |
| 126 | // Check if we've already attempted to read the token |
| 127 | const cachedToken = getSessionIngressToken() |
| 128 | if (cachedToken !== undefined) { |
| 129 | return cachedToken |
| 130 | } |
| 131 | |
| 132 | const fdEnv = process.env.CLAUDE_CODE_WEBSOCKET_AUTH_FILE_DESCRIPTOR |
| 133 | if (!fdEnv) { |
| 134 | // No FD env var — either we're not in CCR, or we're a subprocess whose |
| 135 | // parent stripped the (useless) FD env var. Try the well-known file. |
| 136 | const path = |
| 137 | process.env.CLAUDE_SESSION_INGRESS_TOKEN_FILE ?? |
| 138 | CCR_SESSION_INGRESS_TOKEN_PATH |
| 139 | const fromFile = readTokenFromWellKnownFile(path, 'session ingress token') |
| 140 | setSessionIngressToken(fromFile) |
| 141 | return fromFile |
| 142 | } |
| 143 | |
| 144 | const fd = parseInt(fdEnv, 10) |
| 145 | if (Number.isNaN(fd)) { |
| 146 | logForDebugging( |
| 147 | `CLAUDE_CODE_WEBSOCKET_AUTH_FILE_DESCRIPTOR must be a valid file descriptor number, got: ${fdEnv}`, |
| 148 | { level: 'error' }, |
| 149 | ) |
| 150 | setSessionIngressToken(null) |
| 151 | return null |
| 152 | } |
| 153 | |
| 154 | try { |
| 155 | // Read from the file descriptor |
| 156 | // Use /dev/fd on macOS/BSD, /proc/self/fd on Linux |
| 157 | const fsOps = getFsImplementation() |
| 158 | const fdPath = |
| 159 | process.platform === 'darwin' || process.platform === 'freebsd' |
| 160 | ? `/dev/fd/${fd}` |
| 161 | : `/proc/self/fd/${fd}` |
| 162 | |
| 163 | const token = fsOps.readFileSync(fdPath, { encoding: 'utf8' }).trim() |
| 164 | if (!token) { |
| 165 | logForDebugging('File descriptor contained empty token', { |
| 166 | level: 'error', |
| 167 | }) |
| 168 | setSessionIngressToken(null) |
| 169 | return null |
| 170 | } |
| 171 | logForDebugging(`Successfully read token from file descriptor ${fd}`) |
| 172 | setSessionIngressToken(token) |
| 173 | maybePersistTokenForSubprocesses( |
| 174 | CCR_SESSION_INGRESS_TOKEN_PATH, |
| 175 | token, |
| 176 | 'session ingress token', |
| 177 | ) |
| 178 | return token |
| 179 | } catch (error) { |
| 180 | logForDebugging( |
| 181 | `Failed to read token from file descriptor ${fd}: ${errorMessage(error)}`, |
| 182 | { level: 'error' }, |
no test coverage detected