( binding: SessionBinding | undefined, config: ServerConfig, deps: ServerDependencies, feedPolicy: SessionBoundFeedPolicy = 'restart' )
| 253 | return { |
| 254 | ptyId, |
| 255 | action: match[2] === 'connect' ? 'connect' : undefined, |
| 256 | }; |
| 257 | } |
| 258 | |
| 259 | async function notifySessionBound( |
| 260 | deps: ServerDependencies, |
| 261 | feedPolicy: SessionBoundFeedPolicy |
| 262 | ): Promise<void> { |
| 263 | if (!deps.onSessionBound) return; |
| 264 | try { |
| 265 | await deps.onSessionBound(feedPolicy); |
| 266 | } catch (error) { |
| 267 | logToFile( |
| 268 | `session-bound callback failed: ${error instanceof Error ? error.message : String(error)}` |
| 269 | ); |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | export async function bindSessionContext( |
| 274 | binding: SessionBinding | undefined, |
| 275 | config: ServerConfig, |
| 276 | deps: ServerDependencies, |
| 277 | feedPolicy: SessionBoundFeedPolicy = 'restart', |
| 278 | /** |
| 279 | * The kiloSessionId to bind, when the caller already knows it (e.g. from a |
| 280 | * fresh session/ready request) but hasn't yet written it back to `config`. |
| 281 | * Falls back to `config.sessionId` for callers that rebind an |
| 282 | * already-bootstrapped wrapper, where `config.sessionId` is already current. |
| 283 | */ |
| 284 | kiloSessionIdOverride?: string, |
| 285 | logArchiveId?: string |
| 286 | ): Promise<Response | null> { |
| 287 | const { state } = deps; |
| 288 | const kiloSessionId = kiloSessionIdOverride ?? config.sessionId; |
| 289 | const blockedWrapperRunId = state.finalizingWrapperRunId; |
| 290 | const isFreshRunAfterFinalization = |
| 291 | state.admissionsBlocked && |
| 292 | !state.hasSession && |
| 293 | blockedWrapperRunId !== undefined && |
| 294 | binding?.wrapperRunId !== undefined && |
| 295 | binding.wrapperRunId !== blockedWrapperRunId; |
| 296 | |
| 297 | if (state.admissionsBlocked && !isFreshRunAfterFinalization) { |
| 298 | return wrapperFinalizingResponse(state); |
| 299 | } |
| 300 | |
| 301 | if (!binding) { |
| 302 | if (!state.hasSession) { |
| 303 | return errorResponse('NO_SESSION', 'No session context and no binding provided', 400); |
| 304 | } |
| 305 | return null; |
| 306 | } |
| 307 | |
| 308 | const missingFields: string[] = []; |
| 309 | if (!binding.wrapperRunId) missingFields.push('wrapperRunId'); |
| 310 | if (binding.wrapperGeneration === undefined || binding.wrapperGeneration === null) { |
| 311 | missingFields.push('wrapperGeneration'); |
| 312 | } |
no test coverage detected