Claude Code: Bridge Layer (การเชื่อมต่อ IDE)

🇹🇭 Thai claude-codebridgeide-integrationanalysisthai
📋 Table of Contents (7 sections)
  1. Bridge Layer (VS Code / JetBrains IDE Integration)
  2. ภาพรวมสถาปัตยกรรม
  3. Feature Gate Analysis
  4. Bridge Stub
  5. Bridge Activation (งานในอนาคต)
  6. Chrome Extension Bridge
  7. สรุปการตรวจสอบ

Bridge Layer (VS Code / JetBrains IDE Integration)

ภาพรวมสถาปัตยกรรม

Bridge (src/bridge/, ~31 ไฟล์) เชื่อมต่อ Claude Code CLI sessions กับ IDE extensions ระยะไกล (VS Code, JetBrains) และ claude.ai web UI โดยถูก gate ไว้หลัง feature('BRIDGE_MODE') ซึ่งค่าเริ่มต้นเป็น false

Protocols

Bridge ใช้ two transport generations:

VersionRead PathWrite PathNegotiation
v1 (env-based)WebSocket ไปยัง Session-Ingress (ws(s)://.../v1/session_ingress/ws/{sessionId})HTTP POST ไปยัง Session-IngressEnvironments API poll/ack/dispatch
v2 (env-less)SSE stream ผ่าน SSETransportCCRClient/worker/* endpointsDirect POST /v1/code/sessions/{id}/bridge → worker JWT

ทั้งคู่ wrap อยู่หลัง interface ReplBridgeTransport (replBridgeTransport.ts)

เส้นทาง v1: ลงทะเบียน environment → poll หางาน → acknowledge → spawn session เส้นทาง v2: สร้าง session → POST /bridge เพื่อรับ JWT → SSE + CCRClient โดยตรง

Authentication

  1. OAuth tokens — ต้องการ claude.ai subscription (isClaudeAISubscriber())
  2. JWT — Session-Ingress tokens (นำหน้าด้วย sk-ant-si-) พร้อม exp claims jwtUtils.ts decode และกำหนดเวลา refresh เชิงรุกก่อนหมดอายุ
  3. Trusted Device token — header X-Trusted-Device-Token สำหรับ sessions ที่มีความปลอดภัยสูง ลงทะเบียนผ่าน trustedDevice.ts
  4. Environment secretWorkSecret ที่ encode ด้วย base64url ประกอบด้วย session_ingress_token, api_base_url, git sources, auth tokens

Dev override: CLAUDE_BRIDGE_OAUTH_TOKEN และ CLAUDE_BRIDGE_BASE_URL (เฉพาะ ant, process.env.USER_TYPE === 'ant')

Message Flow (IDE ↔ CLI)

IDE / claude.ai  ──WebSocket/SSE──→  Session-Ingress  ──→  CLI (replBridge)
   ←── POST / CCRClient writes ────  Session-Ingress  ←──  CLI

Inbound (server → CLI):

  • user messages (prompts จาก web UI) → handleIngressMessage() → เข้าคิวไปยัง REPL
  • control_request (initialize, set_model, interrupt, set_permission_mode, set_max_thinking_tokens)
  • control_response (การตัดสินใจ permission จาก IDE)

Outbound (CLI → server):

  • assistant messages (การตอบของ Claude)
  • user messages (echo เพื่อ sync)
  • result messages (การสิ้นสุด turn)
  • System events, tool starts, activities

Dedup: BoundedUUIDSet ติดตาม UUIDs ที่ posted/inbound เมื่อเร็วๆ นี้เพื่อปฏิเสธ echoes และการส่งซ้ำ

Lifecycle

  1. Entitlement check: isBridgeEnabled() / isBridgeEnabledBlocking() → GrowthBook gate tengu_ccr_bridge + OAuth subscriber check
  2. Session creation: createBridgeSession() → POST ไปยัง API
  3. Transport init: v1 HybridTransport หรือ v2 SSETransport + CCRClient
  4. Message pump: อ่าน inbound ผ่าน transport เขียน outbound ผ่าน batch
  5. Token refresh: JWT refresh เชิงรุกผ่าน createTokenRefreshScheduler()
  6. Teardown: teardown() → flush pending → ปิด transport → archive session

Spawn modes สำหรับ claude remote-control:

  • single-session: Session เดียวใน cwd bridge จะปิดเมื่อจบ
  • worktree: Persistent server แต่ละ session ได้รับ isolated git worktree
  • same-dir: Persistent server sessions ใช้ cwd ร่วมกัน

Key Types

  • BridgeConfig — การตั้งค่า bridge ทั้งหมด (dir, auth, URLs, spawn mode, timeouts)
  • WorkSecret — Decoded work payload (token, API URL, git sources, MCP config)
  • SessionHandle — Running session (kill, activities, stdin, token update)
  • ReplBridgeHandle — REPL bridge API (write messages, control requests, teardown)
  • BridgeState'ready' | 'connected' | 'reconnecting' | 'failed'
  • SpawnMode'single-session' | 'worktree' | 'same-dir'

Feature Gate Analysis

Must Work (ทำงานถูกต้องในปัจจุบัน)

gate feature('BRIDGE_MODE') ใน src/shims/bun-bundle.ts ค่าเริ่มต้นเป็น false (อ่านจาก env var CLAUDE_CODE_BRIDGE_MODE) code paths วิกฤตทั้งหมด ได้รับการ guard อย่างเหมาะสม:

LocationGuard
src/entrypoints/cli.tsx:112feature('BRIDGE_MODE') && args[0] === 'remote-control'
src/main.tsx:2246feature('BRIDGE_MODE') && remoteControlOption !== undefined
src/main.tsx:3866if (feature('BRIDGE_MODE')) (Commander subcommand)
src/hooks/useReplBridge.tsx:79-88useAppState calls ทั้งหมด gate ด้วย feature('BRIDGE_MODE') ternary
src/hooks/useReplBridge.tsx:99useEffect body gate ด้วย feature('BRIDGE_MODE')
src/components/PromptInput/PromptInputFooter.tsx:160if (!feature('BRIDGE_MODE')) return null
src/components/Settings/Config.tsx:930feature('BRIDGE_MODE') && isBridgeEnabled() spread
src/tools/BriefTool/upload.ts:99if (feature('BRIDGE_MODE'))
src/tools/ConfigTool/supportedSettings.ts:153feature('BRIDGE_MODE') spread

Can Defer (bridge functionality เต็มรูปแบบ)

สิ่งต่อไปนี้ทั้งหมดอยู่หลัง feature gate และไม่ active:

  • runBridgeLoop() — Bridge orchestration เต็มรูปแบบใน bridgeMain.ts
  • initReplBridge() — REPL bridge initialization
  • initBridgeCore() / initEnvLessBridgeCore() — Transport negotiation
  • createBridgeApiClient() — Environments API calls
  • BridgeUI — Bridge status display และ QR codes
  • Token refresh scheduling
  • Multi-session management (worktree mode)
  • Permission delegation ไปยัง IDE

Won’t Break

Static imports ของ bridge modules จากนอก src/bridge/ ไม่ crash เพราะ:

  1. Bridge files ทั้งหมดมีอยู่จริง — อยู่ใน repo imports จึง resolve ได้
  2. ไม่มี side effects ตอน import — bridge modules นิยาม functions/types แต่ไม่ execute bridge logic เมื่อ import
  3. Runtime guards — Functions เช่น isBridgeEnabled() คืนค่า false เมื่อ feature('BRIDGE_MODE') เป็น false getReplBridgeHandle() คืนค่า null useReplBridge short-circuits ผ่าน ternary operators

ไฟล์ที่มี static imports ที่ไม่ได้ guard (ปลอดภัยเพราะ files มีอยู่จริง):

  • src/hooks/useReplBridge.tsx — import types และ utils จาก bridge
  • src/components/Settings/Config.tsx — import isBridgeEnabled (คืนค่า false)
  • src/components/PromptInput/PromptInputFooter.tsx — early-returns null
  • src/tools/SendMessageTool/SendMessageTool.tsgetReplBridgeHandle() คืนค่า null
  • src/tools/BriefTool/upload.ts — guard ที่ call site
  • src/commands/logout/logout.tsxclearTrustedDeviceTokenCache เป็น no-op

Bridge Stub

สร้าง src/bridge/stub.ts พร้อม:

  • isBridgeAvailable() → คืนค่า false เสมอ
  • noopBridgeHandle — silent no-op ReplBridgeHandle
  • noopBridgeLogger — silent no-op BridgeLogger

พร้อมใช้สำหรับโค้ดในอนาคตที่ต้องการ fallback ที่ปลอดภัยเมื่อ bridge ปิด


Bridge Activation (งานในอนาคต)

เพื่อเปิดใช้งาน bridge:

1. Environment Variable

export CLAUDE_CODE_BRIDGE_MODE=true

2. Authentication Requirements

  • ต้อง login เข้า claude.ai พร้อม active subscription (isClaudeAISubscriber() ต้องคืนค่า true)
  • OAuth tokens ได้มาจาก claude auth login (ต้องการ scope user:profile)
  • GrowthBook gate tengu_ccr_bridge ต้องเปิดใช้งานสำหรับ org ของ user

3. IDE Extension

  • VS Code: Claude Code extension (เชื่อมต่อผ่าน Session-Ingress layer ของ bridge)
  • JetBrains: Integration คล้ายกัน (protocol เดียวกัน)
  • Web: URL claude.ai/code?bridge={environmentId}

4. Network / Ports

  • Session-Ingress: WebSocket (wss://) หรือ SSE สำหรับอ่าน HTTPS POST สำหรับเขียน
  • API base: Production api.claude.ai (ตั้งค่าผ่าน OAuth config)
  • Dev overrides: CLAUDE_BRIDGE_BASE_URL, localhost ใช้ ws:// และ /v2/ paths
  • QR code แสดงใน terminal ลิงก์ไปยัง claude.ai/code?bridge={envId}

5. Running Remote Control

# Single session (ปิดเมื่อ session จบ)
claude remote-control

# Named session
claude remote-control "my-project"

# พร้อม spawn mode เฉพาะ (ต้องการ gate tengu_ccr_bridge_multi_session)
claude remote-control --spawn worktree
claude remote-control --spawn same-dir

6. Additional Flags

  • --remote-control [name] / --rc [name] — เริ่ม REPL พร้อม bridge ที่เปิดไว้ล่วงหน้า
  • --debug-file <path> — เขียน debug log ลงไฟล์
  • --session-id <id> — กลับสู่ session ที่มีอยู่

Chrome Extension Bridge

--claude-in-chrome-mcp (cli.tsx:72)

เปิด Claude-in-Chrome MCP server ผ่าน runClaudeInChromeMcpServer() จาก src/utils/claudeInChrome/mcpServer.ts ซึ่ง:

  • สร้าง StdioServerTransport (MCP over stdin/stdout)
  • ใช้ package @ant/claude-for-chrome-mcp เพื่อสร้าง MCP server
  • Bridge ระหว่าง Claude Code และ Chrome extension
  • รองรับทั้ง native socket (local) และ WebSocket bridge (wss://bridge.claudeusercontent.com)
  • Gate ด้วย GrowthBook flag tengu_copper_bridge (หรือ USER_TYPE=ant)

ไม่ gate ด้วย feature('BRIDGE_MODE') — เป็น subsystem แยกต่างหาก ทำงานเมื่อเรียกด้วย flag --claude-in-chrome-mcp เท่านั้น

--chrome-native-host (cli.tsx:79)

เปิด Chrome Native Messaging Host ผ่าน runChromeNativeHost() จาก src/utils/claudeInChrome/chromeNativeHost.ts ซึ่ง:

  • Implement Chrome’s native messaging protocol (4-byte length prefix + JSON over stdin/stdout)
  • สร้าง Unix domain socket server ที่ secure path
  • Proxy MCP messages ระหว่าง Chrome extension และ Claude Code instances ในเครื่อง
  • มี debug logging ของตัวเองที่ ~/.claude/debug/chrome-native-host.txt (เฉพาะ ant)

ไม่ gate ด้วย feature('BRIDGE_MODE') — entry point แยกต่างหาก เปิดใช้เฉพาะเมื่อ Chrome เรียก registered native messaging host binary

Safety

เส้นทาง Chrome ทั้งคู่:

  • เป็น dynamic imports — โหลดเฉพาะเมื่อมี flag เฉพาะ
  • Return ทันทีหลัง await ของตัวเอง — ไม่มี side effects เมื่อ CLI เริ่มปกติ
  • ไม่สามารถ crash การทำงานปกติได้เพราะเป็น code paths แยกต่างหากทั้งหมด
  • ไม่มี dependency กับ bridge feature flag

สรุปการตรวจสอบ

การตรวจสอบสถานะ
feature('BRIDGE_MODE') คืนค่า false โดยค่าเริ่มต้น✅ ตรวจสอบแล้วใน src/shims/bun-bundle.ts
Bridge code ไม่ execute เมื่อปิดการใช้งาน✅ call sites ทั้งหมดใช้ feature() guard
ไม่มี bridge-related errors เมื่อเริ่มต้น✅ Imports resolve (files มีอยู่จริง) ไม่มี side effects
CLI ทำงานใน terminal-only mode✅ Bridge เป็น purely additive
Chrome paths ไม่ crash✅ Dynamic imports แยกต่างหาก เฉพาะ flags ที่ชัดเจน
Stub พร้อมใช้เพื่อความปลอดภัย✅ สร้าง src/bridge/stub.ts แล้ว
← Back to claudecodeanalysis