(
streamUrl: string,
initialPrompt?: AsyncIterable<string>,
replayUserMessages?: boolean,
sessionIdOverride?: string,
)
| 142 | private readonly sessionId: string | undefined |
| 143 | |
| 144 | constructor( |
| 145 | streamUrl: string, |
| 146 | initialPrompt?: AsyncIterable<string>, |
| 147 | replayUserMessages?: boolean, |
| 148 | sessionIdOverride?: string, |
| 149 | ) { |
| 150 | const inputStream = new PassThrough({ encoding: 'utf8' }) |
| 151 | super(inputStream, replayUserMessages) |
| 152 | this.inputStream = inputStream |
| 153 | this.url = new URL(streamUrl) |
| 154 | this.sessionId = sessionIdOverride ?? getSessionId() |
| 155 | this.shouldReplayHistoricalSessionEvents = |
| 156 | !!replayUserMessages && !!buildHistoricalSessionEventsUrl(this.url, this.sessionId) |
| 157 | |
| 158 | // Prepare headers with session ingress auth if available. |
| 159 | const headers: Record<string, string> = getSessionIngressAuthHeaders() |
| 160 | if (Object.keys(headers).length === 0) { |
| 161 | logForDebugging('[remote-io] No session ingress token available', { |
| 162 | level: 'error', |
| 163 | }) |
| 164 | } |
| 165 | |
| 166 | // Add environment runner version if available (set by Environment Manager) |
| 167 | const erVersion = process.env.CLAUDE_CODE_ENVIRONMENT_RUNNER_VERSION |
| 168 | if (erVersion) { |
| 169 | headers['x-environment-runner-version'] = erVersion |
| 170 | } |
| 171 | |
| 172 | // Provide a callback that re-reads the session token dynamically. |
| 173 | // When the parent process refreshes the token (via token file or env var), |
| 174 | // the transport can pick it up on reconnection. |
| 175 | const refreshHeaders = (): Record<string, string> => { |
| 176 | const h: Record<string, string> = getSessionIngressAuthHeaders() |
| 177 | const freshErVersion = process.env.CLAUDE_CODE_ENVIRONMENT_RUNNER_VERSION |
| 178 | if (freshErVersion) { |
| 179 | h['x-environment-runner-version'] = freshErVersion |
| 180 | } |
| 181 | return h |
| 182 | } |
| 183 | |
| 184 | // Get appropriate transport based on URL protocol |
| 185 | this.transport = getTransportForUrl( |
| 186 | this.url, |
| 187 | headers, |
| 188 | this.sessionId, |
| 189 | refreshHeaders, |
| 190 | ) |
| 191 | |
| 192 | // Set up data callback |
| 193 | this.isBridge = process.env.CLAUDE_CODE_ENVIRONMENT_KIND === 'bridge' |
| 194 | this.isDebug = isDebugMode() |
| 195 | this.transport.setOnData((data: string) => { |
| 196 | this.inputStream.write(data.endsWith('\n') ? data : `${data}\n`) |
| 197 | if (this.isBridge && this.isDebug) { |
| 198 | writeToStdout(data.endsWith('\n') ? data : data + '\n') |
| 199 | } |
| 200 | }) |
| 201 |
nothing calls this directly
no test coverage detected