MODULO 6.1

🌉 Bridge & Remote Control

6
Topicos
~60
Minutos
Deep
Nivel
Source
Tipo
1

🌍 Architecture Overview

Outbound (local → cloud)

Claude's messages, tool activities, and result events stream to CCR for real-time rendering on claude.ai.

Inbound (cloud → local)

User prompts, permission decisions, interrupt signals, and control messages flow back to the Claude process.

Auth Boundary

Bridge API calls use OAuth token. CCR worker endpoints validate a short-lived JWT encoding session_id and role=worker claims.

2

🔄 Bridge v1 vs v2

v1 — Environment-based

Registers via POST /v1/environments, polls for work, decodes WorkSecret (base64url JSON), supports perpetual mode and multi-session spawn. Transport: HybridTransport (WebSocket reads + HTTP POSTs).

v2 — Environment-less

No Environments API. POST /v1/code/sessions → session ID. POST /v1/code/sessions/{id}/bridge → worker JWT + epoch. Transport: SSETransport (reads) + CCRClient (writes). Gated by tengu_bridge_repl_v2 GrowthBook flag.

💡 WorkSecret Decode

When the Environments API delivers work, it attaches an opaque secret field that is a base64url-encoded JSON blob containing session_ingress_token (JWT), api_base_url, sources, and auth arrays.

3

🔌 Transport Layer

ReplBridgeTransport Interface

Unified interface: write(), writeBatch(), close(), isConnectedStatus(), setOnData(), connect(), getLastSequenceNum(), flush(). v2 adds reportState(), reportMetadata(), reportDelivery().

v1 HybridTransport

WebSocket for inbound, HTTP POST for outbound. v1 never uses SSE sequence numbers — server-side cursor handles replay.

v2 SSETransport + CCRClient

Asymmetric: reads via SSE, writes via CCRClient posting to /worker/events. ACK 'processed' immediately to prevent phantom prompt floods.

💡 FlushGate

Prevents history/live message interleaving. Historical messages are flushed as one HTTP batch on connect; live messages arriving during that window are queued and drained after flush completes.

4

🔒 Permission Bridge

Remote Control surfaces tool-use permission prompts through the control_request / control_response protocol. When Claude wants to run a potentially dangerous tool, the question travels through the bridge to claude.ai.

control_request

Bridge asks claude.ai 'can this tool run?'

control_response

claude.ai answers allow/deny, optionally with updated input.

Synthetic AssistantMessage

When a permission request comes from remote CCR, no local message exists. remotePermissionBridge.ts fabricates one with tool stubs for unknown MCP tools.

5

⚙️ Remote Control Command

The /remote-control slash command checks if a bridge is already connected, runs pre-flight checks (checkBridgePrerequisites), then sets replBridgeEnabled: true in AppState.

💡 Five Entitlement Gates

Runtime gate (GrowthBook flag + OAuth sub), OAuth token present, Organization policy (allow_remote_control), Token freshness (proactive refresh), Min version check. If any gate fails, onStateChange 'failed' is called.

6

📡 CCR Integration

SessionsWebSocket

Connects to wss://api.anthropic.com/v1/sessions/ws/{sessionId}/subscribe for real-time event stream.

SDKMessage Adapter

Translates SDK-format messages (assistant, stream_event, result, system) to REPL's internal Message type.

Standalone Bridge

claude remote-control server mode manages concurrent child Claude processes with configurable pool size (default 32) and 24h per-session timeout.

💡 Session ID Compatibility

Infrastructure uses cse_* IDs; frontend uses session_*. Both are the same UUID with different prefixes. sameSessionId() compares by UUID body.

📋 Resumo do Modulo

Two bridge architectures coexist: v1 (env-based poll/ack/heartbeat) and v2 (env-less, direct OAuth to worker JWT via POST /bridge).
Transport is asymmetric in v2: inbound uses SSE with sequence numbers, outbound uses CCRClient posting to /worker/events.
FlushGate prevents history/live message interleaving during session initialization.
Permission flow is bidirectional: control_request travels from Claude to server to claude.ai; control_response travels back.
Session IDs have two costumes: cse_* (infra) and session_* (frontend). sameSessionId() compares UUID body.
Auth for worker endpoints requires JWT, not OAuth. Token refresh triggers server re-dispatch.
Voltar Proximo