Skip to content
源码分析手册

桌面与 Web 平台:CLI 引擎的云端化与多端协同

Claude Code 的演进代表了开发者工具从“本地单机工具”向“分布式代理系统”的架构转变。通过引入 Bridge 架构和多平台支持,Claude Code 实现了 CLI 的轻量化、Web 的便捷化以及桌面端的可视化协同。

从定义开始

从本质上看,Claude Code 不再仅仅是一个运行在终端里的 Node.js 程序,而是一个基于 “Runner-UI” 分离架构 的分布式系统。

在这个体系中,CLI 扮演的是 Runner(执行引擎) 的角色:它拥有本地文件系统的访问权限、Git 的操作权和 Shell 的执行力。而桌面应用(Desktop)和 Web 平台则是 Steering(操控界面):它们负责提供富文本交互、可视化 Diff 预览、多会话管理以及“计算机使用”(Computer Use)等高阶能力。

这种架构的核心在于 Bridge(桥接器)。它允许 CLI 在后台静默运行,通过长轮询或 WebSocket 接收来自云端或桌面端的指令。当你输入 /desktop 时,本质上是让 CLI 进入“受控模式”,将当前会话的上下文锚点同步到 Bridge 服务,从而在桌面应用中无缝接管任务。

代码里的真实逻辑

Claude Code 的跨平台能力依赖于一套严密的远程过程调用(RPC)和会话隔离机制,其核心实现分布在以下几个维度:

1. Bridge 轮询机制

claude-code-opensource/src/bridge/bridgeMain.ts 中,CLI 会作为一个环境(Environment)注册到服务端。它通过 BridgeApiClient 持续轮询(Poll)新的工作任务。一旦服务端下发了 Work(如新的编码请求),本地引擎就会被激活。

2. 基于 Git Worktree 的多任务并行

为了支持桌面端引以为傲的“并行会话”(Parallel Sessions),Claude Code 在 claude-code-opensource/src/utils/worktree.ts 中重度依赖了 Git 的 worktree 特性。

  • 每当桌面端发起一个新的并行任务,本地 Runner 会创建一个独立的 Git 工作树。
  • 这保证了即使你在同一个仓库里让 Claude 修复三个不同的 Bug,它们的文件变更、测试执行和环境状态都是物理隔离的,互不干扰。

3. 会话后台化(Backgrounding)

claude-code-opensource/src/tasks/LocalMainSessionTask.ts 实现了 CLI 内部的异步执行逻辑。当你在终端按下 Ctrl+B 后,当前的 Query 会被转化为一个后台任务。它复用了 LocalAgentTask 的状态机,在执行完成后通过 XML 标签(如 <task-notification>)向 UI 发送信号。这种机制是 CLI 能够被桌面端平滑接管的技术前提。

4. 远程控制与安全认证

为了确保远程指令的安全性,Bridge 采用 JWT(JSON Web Token)和设备信任令牌(Trusted Device Token)。在 src/bridge/bridgeApi.ts 中可以看到,所有发往 Bridge 的请求都必须携带 X-Trusted-Device-Token,这确保了只有经过身份验证的设备才能远程操控你的本地代码库。

使用时的关键约束

在使用跨平台功能时,开发者必须理解以下技术约束:

  • 平台能力不对等:计算机使用(Computer Use)目前仅限 macOS 桌面端且需要 Pro/Max 账户;而 Web 端(claude.ai/code)目前主要针对 GitHub 托管的仓库,无法直接访问未联网的本地私有文件。
  • 会话接管的单向性:你可以轻松地将本地会话通过 /desktop 提升到桌面,或者通过 /web-setup 开启云端同步,但将一个高度依赖图形化 Diff 的桌面会话“降级”回纯文本 CLI 时,可能会丢失部分视觉反馈。
  • 网络依赖:Bridge 模式要求 Runner 必须能够访问 Anthropic 的 API 端点。在严格的企业内网环境下,需要配置 HTTP_PROXY 并在防火墙开通特定的域名白名单。
  • Git 隔离代价:虽然 Git Worktree 实现了并行隔离,但频繁创建工作树会占用额外的磁盘空间。如果你的仓库极其庞大(数 GB 级别),开启过多并行任务可能会导致磁盘压力。

接下来看什么

  • 安全与沙箱 (06-security-and-sandboxing.md):深入了解 Bridge 模式下如何防止恶意的远程指令注入。
  • 代理协作 (08-agent-collaboration.md):研究 Dispatch 功能如何跨越手机端与桌面端,实现“手机发指令,电脑写代码”。

源码锚点

  • claude-code-opensource/src/bridge/bridgeApi.ts:Bridge 协议的 API 定义与错误处理。
📄 src/bridge/bridgeApi.ts — Bridge 协议的 API 定义与错误处理。L6-12 of 540
typescript
  type BridgeApiClient,
  type BridgeConfig,
  type PermissionResponseEvent,
  type WorkResponse,
} from './types.js'

type BridgeApiDeps = {
  • claude-code-opensource/src/tasks/LocalMainSessionTask.ts:主会话任务后台化与状态管理的逻辑核心。
📄 src/tasks/LocalMainSessionTask.ts — 主会话任务后台化与状态管理的逻辑核心。L35-37 of 480
typescript
  type SubagentContext,
} from '../utils/agentContext.js'
import { registerCleanup } from '../utils/cleanupRegistry.js'
  • claude-code-opensource/src/bridge/bridgeMain.ts:CLI 作为本地 Worker 运行的主循环逻辑。
📄 src/bridge/bridgeMain.ts — CLI 作为本地 Worker 运行的主循环逻辑。L112-124 of 3000
typescript
 * Returns the args that must precede CLI flags when spawning a child claude
 * process. In compiled binaries, process.execPath is the claude binary itself
 * and args go directly to it. In npm installs (node running cli.js),
 * process.execPath is the node runtime — the child spawn must pass the script
 * path as the first arg, otherwise node interprets --sdk-url as a node option
 * and exits with "bad option: --sdk-url". See anthropics/claude-code#28334.
 */
function spawnScriptArgs(): string[] {
  if (isInBundledMode() || !process.argv[1]) {
    return []
  }
  return [process.argv[1]]
}
  • claude-code-opensource/src/utils/worktree.ts:实现多任务并行隔离的 Git 底层支撑。
📄 src/utils/worktree.ts — 实现多任务并行隔离的 Git 底层支撑。L24-27 of 1520
typescript
  resolveGitDir,
  resolveRef,
} from './git/gitFilesystem.js'
import {

基于 Claude Code v2.1.88 开源快照的深度分析