架构主线 · 04

服务与外部集成

services 和 utils 撑起 CLI 的外围能力:多 provider API、MCP、插件与技能、权限、长上下文、LSP/IDE/Chrome、远程桥接和托管设置。

1. services 与 utils 的分工#

src/services 更像业务服务层:API、MCP、analytics、compact、LSP、OAuth、remote managed settings、policy limits、memory sync 等都在这里。

src/utils 是最大目录,更像横切基础设施层:plugins、permissions、settings、model、bash、shell、computer use、telemetry、worktree、session storage、secure storage、hooks、teleport 等都在这里。

简单说:

2. API 与模型 provider#

src/services/api/client.ts 把多种模型后端统一成 Anthropic SDK 风格客户端。支持的主要分支:

Provider触发条件认证/配置要点
Anthropic first-party默认API key 或 Claude.ai OAuth token,自定义 headers,base URL,request id
BedrockCLAUDE_CODE_USE_BEDROCKAWS region、小模型 region override、AWS bearer token、AWS credential refresh
FoundryCLAUDE_CODE_USE_FOUNDRYAzure Foundry API key 或 Azure AD DefaultAzureCredential
VertexCLAUDE_CODE_USE_VERTEXGCP credential refresh、GoogleAuth、model-specific region、project id fallback

client 统一注入 x-app、User-Agent、session id、container/remote session id、SDK client app 等 headers。对 first-party API,还会通过 fetch wrapper 添加 x-client-request-id,让 timeout 等无服务端 request id 的故障也能关联日志。

这个设计说明模型 provider 兼容是运行时能力,而不是编译时换包。

3. Analytics、GrowthBook、Telemetry#

services/analytics 不只是统计事件,也承担 feature gate 动态控制。几个关键点:

也就是说,analytics 层同时是观测系统和动态配置系统。

4. MCP 子系统#

src/services/mcp/client.ts 是最复杂的服务之一,MCP 在这里已经是一条完整产品线。

支持的 transport

代码里能看到这些 server 类型:

MCP transport 处理了很多真实环境问题:

MCP tool/prompt/resource 映射

MCP server 连接成功后会并行抓取:

MCP tool 转内部 Tool 时会处理:

MCP prompt 会转成 type: 'prompt' 的 Command,名字形如 mcp__server__prompt,执行时调用 client.getPrompt() 并把返回 content 转成模型消息块。

MCP result 处理

MCP 结果不是直接塞上下文:

URL elicitation 也被纳入工具调用流程:当 MCP 返回 UrlElicitationRequired (-32042) 时,会先跑 hooks,再根据 headless/SDK 或 REPL 走 structuredIO callback 或 UI queue,用户完成后重试 tool call,最多 3 次。

5. MCP 与上层产品的连接#

MCP 不是孤立 service,它贯穿多层:

这就是为什么文档里说 MCP 是“完整产品线”,而不是简单第三方接口。

6. 插件与技能生态#

插件相关代码主要分布在:

Skills 也有多来源:skills/bundled、用户 skill dirs、plugin skills、builtin plugin skills、dynamic skills、MCP skills。

命令系统会把它们统一成 prompt 型 Command,再由 SkillTool 暴露给模型。这说明“插件 + MCP + 技能”在产品上已经趋向统一扩展生态。

7. 权限与安全基础设施#

权限涉及多个目录:

权限规则支持多来源:settings、policy、flag、CLI arg、command、session。规则可以是整工具,也可以是内容级,例如 Bash(git status:*) 或 MCP server-level mcp__server。关键安全特征:

8. Compact、memory 与上下文治理#

长上下文治理散布在几处:

这说明项目把 token/context 当成长期运行时资源管理,而不是“超过就报错”。reactive compact / context collapse 走 query.ts 与 compact / microcompact / session-memory compact 这些路径。

9. LSP、IDE、Chrome、Computer Use#

外部开发环境集成主要包括:

这些能力说明 CLI 的“外部世界”不只是文件系统和 shell,还包括 IDE、浏览器、桌面应用和远程会话。

10. Remote bridge / CCR#

src/bridge 是远程控制与 session ingress 的主链路。这里有两类重要路径。

env-based bridge:bridgeMain.ts / replBridge.ts

传统路径会注册 environment、创建 session、poll work、spawn child CLI、heartbeat、stop work、cleanup。bridgeMain.tsrunBridgeLoop() 管理:active sessions;work id 与 session id 映射;session ingress JWT;token refresh;heartbeat 与 auth failure re-dispatch;worktree 创建/删除;timeout watchdog;capacity wake;fatal backoff 与 shutdown cleanup。

sessionRunner.ts 会真正 spawn 子进程:

claude --print --sdk-url <url> --session-id <id>
       --input-format stream-json --output-format stream-json
       --replay-user-messages

子进程环境会带 CLAUDE_CODE_SESSION_ACCESS_TOKEN,并可启用 CCR v2 env vars。父进程解析子进程 stdout NDJSON,提取 tool activity、assistant text、result、control_request,并通过 stdin 下发 token refresh 或控制消息。

env-less bridge:remoteBridgeCore.ts

remoteBridgeCore.ts 明确说明了“env-less Remote Control bridge core”:

  1. POST /v1/code/sessions 创建 session;
  2. POST /v1/code/sessions/{id}/bridge 用 OAuth 换 worker JWT、api base URL、worker epoch;
  3. createV2ReplTransport() 建 SSE + CCRClient;
  4. token refresh 时重新调用 /bridge,因为每次会 bump epoch;
  5. SSE 401 时重建 transport。

它去掉了 Environments API 的 register/poll/ack/stop/heartbeat/deregister 生命周期,更适合 REPL 远程控制。文件注释也强调:env-less 说的是去掉 environment/poll dispatch 层,不等同于 CCR v2 transport 本身。

11. remote / server / cli transport#

这些模块共同把本地 CLI、SDK、远程 Web/Mobile、CCR worker 串起来。

12. Settings、remote managed settings、policy limits#

设置系统散布在:

关键设计是“trust 前后分层”:trust 前只应用 safe env;trust 后才完整应用环境与遥测。远端策略还能在会话中禁用 bypass permissions 等高风险能力。

13. vendor 目录#

recovered/vendor 只有四个包装:

数量少但意义明确:平台/原生能力被封装在 vendor 层,主仓主体仍是 TypeScript 业务与运行时代码。

14. 这一层的结论#

这一层覆盖的外围能力: