Claude Code의 IDE 브릿지(Remote Control Bridge)는 로컬 개발 환경과 claude.ai 웹 클라이언트 사이의 양방향 통신 채널을 구현한다. 단순한 WebSocket 래퍼가 아니라, 환경 등록(Environment Registration), 작업 폴링(Work Polling), 세션 수명주기 관리, JWT 기반 토큰 갱신을 통합한 완결된 원격 제어 프레임워크다.
브릿지는 두 가지 아키텍처 경로를 지원한다:
- **환경 기반 경로(Env-based, `bridgeMain.ts`)**: Environments API 레이어를 통해 작업을 디스패치하는 고전적 방식. `claude remote-control` 명령이 이 경로를 사용한다.
- **환경 비의존 경로(Env-less, `remoteBridgeCore.ts`)**: `/v1/code/sessions/{id}/bridge` 엔드포인트를 통해 직접 세션 인그레스에 연결하는 신형 경로. REPL 전용이며 `tengu_bridge_repl_v2` GrowthBook 플래그로 활성화된다.
const FALLBACK_REFRESH_INTERVAL_MS = 30 * 60 * 1000 // JWT 불투명 시 30분 주기
const MAX_REFRESH_FAILURES = 3 // 연속 실패 서킷 브레이커
```
**세대(generation) 카운터 패턴**: 비동기 갱신 경쟁 조건을 방지하기 위해 세션별 세대 카운터를 사용한다. `schedule()` 또는 `cancel()` 호출 시 세대가 증가하며, 진행 중인 `doRefresh()`는 세대 불일치를 감지하면 즉시 중단한다.
```typescript
// 세대 불일치 감지 - 갱신 경쟁 방지
if (generations.get(sessionId) !== gen) {
logForDebugging(`stale gen ${gen} vs ${generations.get(sessionId)}, skipping`)
return
}
```
**두 가지 스케줄링 방식**:
-`schedule(sessionId, token)`: JWT `exp` 클레임을 디코딩하여 정확한 타이머 설정
-`scheduleFromExpiresIn(sessionId, expiresInSeconds)`: 서버가 `expires_in`을 직접 반환할 때 사용. `/v1/code/sessions/{id}/bridge` 응답이 이 방식을 사용
갱신 성공 후에는 `FALLBACK_REFRESH_INTERVAL_MS` 뒤에 후속 갱신을 예약하여, 장기 세션에서 인증이 끊기지 않도록 보장한다.
### 3. 환경 비의존 브릿지 코어 (`remoteBridgeCore.ts`)
신형 REPL 브릿지는 Environments API 레이어를 완전히 우회한다. 연결 수립 순서:
```
1. POST /v1/code/sessions (OAuth 인증) → session.id
2. POST /v1/code/sessions/{id}/bridge (OAuth 인증) → {worker_jwt, expires_in, api_base_url, worker_epoch}
`buildSdkUrl()` 및 `buildCCRv2SdkUrl()`은 이 시크릿에서 SDK URL을 구성한다.
### 6. 신뢰 디바이스 토큰 (`trustedDevice.ts`)
`getTrustedDeviceToken()`은 디바이스 식별을 위한 신뢰 토큰을 반환한다. 이 토큰은 환경 등록 요청에 포함되어 백엔드가 재연결 시 동일 디바이스임을 확인하는 데 사용된다.
---
## 설계 결정
### 백오프 전략
연결 실패 시 지수 백오프를 적용하되 두 개의 독립적 파라미터 집합을 사용한다:
```typescript
const DEFAULT_BACKOFF: BackoffConfig = {
connInitialMs: 2_000, // 연결 실패: 2초 시작
connCapMs: 120_000, // 최대 2분
connGiveUpMs: 600_000, // 10분 후 포기
generalInitialMs: 500, // 일반 오류: 500ms 시작
generalCapMs: 30_000, // 최대 30초
generalGiveUpMs: 600_000, // 10분 후 포기
}
```
연결 오류(네트워크 단절)와 일반 오류(API 오류)를 구분하여 서로 다른 백오프 파라미터를 적용한다. 이는 일시적인 네트워크 장애에서 더 공격적으로 재연결을 시도하면서, 서버 측 오류에서는 보수적으로 처리하기 위함이다.
### 다중 세션 GrowthBook 게이팅
다중 세션 생성 모드(`--spawn`, `--capacity`)는 `tengu_ccr_bridge_multi_session` GrowthBook 플래그로 제어된다. 캐시 미스 시에도 차단(blocking) 게이트 확인을 사용하여 내부 사용자가 불공정하게 기능을 거부당하지 않도록 보장한다.
### 멱등 환경 등록
`bridgeId`와 `environmentId`는 모두 클라이언트에서 생성한 UUID다. 브릿지가 재시작될 때 동일한 UUID를 사용하면 백엔드가 중복 환경 생성을 방지할 수 있다. `reuseEnvironmentId`는 `--session-id` 재개 시 백엔드 형식의 환경 ID를 재사용하기 위한 별도 필드다.
### 세션 활동 링 버퍼
`SessionHandle.activities`는 최근 약 10개의 활동을 추적하는 링 버퍼다. 이 설계는 메모리를 상한으로 제한하면서 UI 상태 표시(`bridgeUI.ts`)에 충분한 컨텍스트를 제공한다.
---
## 관련 파일 참조
| 파일 | 역할 |
|------|------|
| `src/bridge/bridgeMain.ts` | 환경 기반 브릿지 진입점, 메인 폴링 루프 |
| `src/bridge/remoteBridgeCore.ts` | 환경 비의존 REPL 브릿지 코어 |