/ bridge / sessionIdCompat.ts
sessionIdCompat.ts
 1  /**
 2   * Session ID tag translation helpers for the CCR v2 compat layer.
 3   *
 4   * Lives in its own file (rather than workSecret.ts) so that sessionHandle.ts
 5   * and replBridgeTransport.ts (bridge.mjs entry points) can import from
 6   * workSecret.ts without pulling in these retag functions.
 7   *
 8   * The isCseShimEnabled kill switch is injected via setCseShimGate() to avoid
 9   * a static import of bridgeEnabled.ts → growthbook.ts → config.ts — all
10   * banned from the sdk.mjs bundle (scripts/build-agent-sdk.sh). Callers that
11   * already import bridgeEnabled.ts register the gate; the SDK path never does,
12   * so the shim defaults to active (matching isCseShimEnabled()'s own default).
13   */
14  
15  let _isCseShimEnabled: (() => boolean) | undefined
16  
17  /**
18   * Register the GrowthBook gate for the cse_ shim. Called from bridge
19   * init code that already imports bridgeEnabled.ts.
20   */
21  export function setCseShimGate(gate: () => boolean): void {
22    _isCseShimEnabled = gate
23  }
24  
25  /**
26   * Re-tag a `cse_*` session ID to `session_*` for use with the v1 compat API.
27   *
28   * Worker endpoints (/v1/code/sessions/{id}/worker/*) want `cse_*`; that's
29   * what the work poll delivers. Client-facing compat endpoints
30   * (/v1/sessions/{id}, /v1/sessions/{id}/archive, /v1/sessions/{id}/events)
31   * want `session_*` — compat/convert.go:27 validates TagSession. Same UUID,
32   * different costume. No-op for IDs that aren't `cse_*`.
33   *
34   * bridgeMain holds one sessionId variable for both worker registration and
35   * session-management calls. It arrives as `cse_*` from the work poll under
36   * the compat gate, so archiveSession/fetchSessionTitle need this re-tag.
37   */
38  export function toCompatSessionId(id: string): string {
39    if (!id.startsWith('cse_')) return id
40    if (_isCseShimEnabled && !_isCseShimEnabled()) return id
41    return 'session_' + id.slice('cse_'.length)
42  }
43  
44  /**
45   * Re-tag a `session_*` session ID to `cse_*` for infrastructure-layer calls.
46   *
47   * Inverse of toCompatSessionId. POST /v1/environments/{id}/bridge/reconnect
48   * lives below the compat layer: once ccr_v2_compat_enabled is on server-side,
49   * it looks sessions up by their infra tag (`cse_*`). createBridgeSession still
50   * returns `session_*` (compat/convert.go:41) and that's what bridge-pointer
51   * stores — so perpetual reconnect passes the wrong costume and gets "Session
52   * not found" back. Same UUID, wrong tag. No-op for IDs that aren't `session_*`.
53   */
54  export function toInfraSessionId(id: string): string {
55    if (!id.startsWith('session_')) return id
56    return 'cse_' + id.slice('session_'.length)
57  }