Files
claude-code/docs/features/remote-control-self-hosting.md
claude-code-best c5edee431f docs: 文档检查/check 20260419 (#296)
* docs: 修复文档巡检发现的 4 处错误

- daemon.md: 反映实际实现状态(supervisor/worker 已实现而非 stub)
- bridge-mode.md: API 操作数量从 7 修正为 9
- web-search-tool.md: 文件路径从 src/tools/ 修正为 packages/builtin-tools/src/tools/
- remote-control-self-hosting.md: 补充缺失的 RCS_WS_IDLE_TIMEOUT 和 RCS_WS_KEEPALIVE_INTERVAL 配置项

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 Safety 和 Context 文档中的代码引用和类型错误

- permission-model: 修正规则来源从"五层"到八层,优先级顺序对齐代码
- permission-model: PermissionUpdate 类型改为实际的 addRules/replaceRules 等
- permission-model: 补充 acceptEdits 和 dontAsk 两种权限模式
- permission-model: DENIAL_LIMITS 字段名对齐实际代码
- plan-mode: 工具路径从 src/tools/ 改为 packages/builtin-tools/src/tools/
- compaction: 修正 COMPACTABLE_TOOLS 和 POST_COMPACT_* 的行号
- project-memory: 修正 ENTRYPOINT_NAME 常量的行号
- system-prompt: 修正 SystemPrompt 类型定义文件路径和多个行号引用

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修复 introduction 文档中的错误路径和行号引用

- why-this-whitepaper.mdx: BashTool 路径从 src/tools/ 修正为 packages/builtin-tools/src/tools/
- what-is-claude-code.mdx: 移除不存在的 Azure provider,改为实际的 7 种 provider
- architecture-overview.mdx: State 类型行号从 204 修正为 207

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修复 conversation/features 文档中的错误

- streaming.mdx: queryStreamRaw → queryModelWithStreaming 函数名修正
- streaming.mdx: Azure 提供商不存在,替换为实际 7 个提供商
- debug-mode.mdx: --inspect-wait 描述错误,实际使用 BUN_INSPECT 环境变量
- buddy.mdx: 补充缺失的 companionReact.ts、CompanionCard.tsx、index.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修复文档巡检中的源码引用错误

- feature-flags.mdx: 修正 feature() 兜底描述,实际从 bun:bundle 导入而非 cli.tsx:3 内联
- feature-flags.mdx: 修正工具 require 路径为 @claude-code-best/builtin-tools 包路径
- ant-only-world.mdx: 修正 tools.ts 中 require 路径为包路径
- ant-only-world.mdx: 修正 INTERNAL_ONLY_COMMANDS 行号 (267-295) 和数量 (24+)
- skills.mdx: 修正 COMMANDS memoize 行号 258 → 299
- mcp-protocol.mdx: 修正 fetchToolsForClient LRU 缓存上限 20 → 100
- streaming.mdx: 修正流式事件引用
- file-operations.mdx: 修正工具路径引用
- search-and-navigation.mdx: 修正搜索工具引用
- shell-execution.mdx: 修正 shell 工具引用
- buddy.mdx: 补充缺失的 frontmatter 字段
- debug-mode.mdx: 修正调试模式描述

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 tools/agent 文档中的文件路径和行号引用

- 修正 TodoWriteTool、AgentTool、ToolSearchTool 等工具路径
  src/tools/ → packages/builtin-tools/src/tools/
- 更新 Tool.ts、tools.ts、BashTool.tsx 中过时的行号引用
- 修正 WebSearchTool/WebFetchTool/EnterWorktreeTool/ExitWorktreeTool 路径
- 修正 AgentTool.tsx 中多行行号引用

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 feature 文档中的文件路径和行号引用

- ultraplan.md: 更新文件行数(525/349/127)
- fork-subagent.md: 路径迁移 src/tools/ → packages/builtin-tools/
- mcp-skills.md: 修正 getMcpSkillCommands 行号 547→604,client.ts 行号 117→129
- kairos.md: 修正 getBriefSection/getProactiveSection 行号
- proactive.md: 修正 getProactiveSection 行号 860→864

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正顶层文档中的路径迁移和行号引用

- auto-updater.md: config.ts 行号 1735→1737,标注未接入启动流程的函数
- external-dependencies.md: WebSearchTool/WebFetchTool 路径迁移到 builtin-tools 包,Vertex 行号修正
- lsp-integration.md: LSPTool 路径从 src/tools/ 迁移到 packages/builtin-tools/
- stub-recovery-design-1-4.md: 修正 Windows 绝对路径链接为标准代码引用

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 task 文档中的文件扩展名和路径引用

- task-004: AssistantSessionChooser.ts → .tsx, assistant.ts → .tsx
- task-003: cli.tsx 行号 249→272, markdownConfigLoader.ts 行号 29→35
- lan-pipes: SendMessageTool 路径迁移到 packages/builtin-tools/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 补充 computer-use-tools-reference 缺失的 Windows 工具

添加遗漏的 open_terminal 和 activate_window 两个 Windows 专属工具,
修正工具总数 37→39,Windows 工具数 10→12。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 audit/bash-classifier/token-budget/tree-sitter 文档

- feature-flags-audit: ScheduleCronTool 路径迁移、DAEMON 状态更新为 COMPLETE、assistant 文件标记已补全、UDS 标记已实现
- bash-classifier: BashPermissionRequest 文件路径修正、withRetry 行号移除
- token-budget: attachments.ts 行号范围修正
- tree-sitter-bash: bashPermissions.ts 路径迁移到 packages/builtin-tools

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 langfuse-monitoring AgentTool 路径迁移

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 bridgeApi 行号和 Tool.ts 行号引用

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 Safety/Extensibility 文档中的工具路径迁移和行号引用

- sandbox.mdx: shouldUseSandbox.ts 和 bashPermissions.ts 路径迁移至 packages/builtin-tools
- why-safety-matters.mdx: bashPermissions.ts 路径迁移(3 处)
- plan-mode.mdx: EnterPlanModeTool/prompt.ts 路径迁移
- auto-mode.mdx: Auto mode 指令行号 3464→3481
- hooks.mdx: AgentTool/runAgent.ts 路径迁移
- skills.mdx: SkillTool.ts 路径迁移
- custom-agents.mdx: Agent built-in 目录和 exploreAgent.ts 路径迁移

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 internals 文档引用计数和路径

- ant-only-world: USER_TYPE 引用计数 465→410+,工具路径迁移到 builtin-tools
- growthbook-ab-testing: growthbook.ts 行数 1156→1258
- hidden-features: 语音模式状态更新(audio-napi 已恢复)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正工具文档中的行号引用

- sub-agents: AgentTool.call 入口行号 340→387
- shell-execution: ShellCommand onTimeout 行号 129→144

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 feature 文档中的状态、路径和计数

- all-features-guide: 修正 feature flag 启用范围(dev only vs dev+build)
- tier3-stubs: 大量状态修正(stub→已实现),缩减过时条目
- workflow-scripts: 路径迁移到 builtin-tools,状态更新
- web-browser-tool: 工具状态缺失→已实现,路径迁移
- context-collapse: CtxInspectTool 状态缺失→已实现
- computer-use: 行号引用更新,平台分发描述修正
- computer-use-tools-reference: 工具数 39→38
- voice-mode: voiceModeEnabled 行数 55→54

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 更新 the-loop 查询循环行号引用

query.ts 代码变更后终止原因行号整体偏移约 40 行

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 补充 feature-flags-audit 完整 build 默认 feature 列表

添加 ULTRATHINK/LODESTONE/ACP/DAEMON 等 19 个缺失的 build 默认 feature,
修正 dev-only 特征标注(UDS_INBOX/LAN_PIPES/BG_SESSIONS/TEMPLATES)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 feature-flags-audit ConfigTool 路径迁移

ConfigTool 路径从 src/tools/ 迁移到 packages/builtin-tools/src/tools/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 feature-flags-audit BashTool 路径迁移

BashTool 路径从 src/tools/ 迁移到 packages/builtin-tools/src/tools/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 feature-flags-audit SkillTool 路径迁移

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 更新 feature-flags-audit WorkflowTool 状态为已实现

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-19 09:30:00 +08:00

353 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Remote Control Server 私有化部署指南
本指南说明如何将 Remote Control Server (RCS) 部署到私有环境,并通过 Claude Code CLI 连接使用。
## 架构概览
```
┌──────────────────┐ ┌──────────────────────┐
│ Claude Code CLI │ ◄── HTTP/SSE/WS ─►│ Remote Control │
│ (Bridge Worker) │ 长轮询 + 心跳 │ Server (RCS) │
└──────────────────┘ │ │
│ ┌──────────────┐ │
┌──────────────────┐ HTTP/SSE │ │ In-Memory │ │
│ Web UI 控制面板 │ ◄─────────────── │ │ Store │ │
│ (/code/*) │ │ └──────────────┘ │
│ (React + Vite) │ │ ┌──────────────┐ │
└──────────────────┘ │ │ JWT Auth │ │
│ └──────────────┘ │
┌──────────────────┐ │ ┌──────────────┐ │
│ acp-link │ ◄── ACP Relay ─── │ │ ACP Handler │ │
│ + ACP Agent │ WebSocket │ └──────────────┘ │
└──────────────────┘ └──────────────────────┘
```
**RCS 是一个纯内存的中间服务**,它的职责是:
- 接收 Claude Code CLI 的环境注册和工作轮询
- 接收 acp-link 的 ACP agent 注册,支持 WebSocket relay 桥接
- 提供 Web UI 供操作者远程监控和审批
- 通过 WebSocket/SSE 双向传输消息
- 管理会话、环境、权限请求
- 提供 ACP SSE event stream 供外部消费者订阅 channel group 事件
## 前置条件
- 一台可被 Claude Code CLI 和 Web 浏览器同时访问的服务器物理机、VM、容器均可
- [Docker](https://www.docker.com/)
- 启用 `BRIDGE_MODE` feature flag 的 Claude Code 构建
## 部署
### 构建 Docker 镜像
在项目根目录执行:
```bash
docker build -t rcs:latest -f packages/remote-control-server/Dockerfile .
```
### 启动容器
```bash
docker run -d \
--name rcs \
-p 3000:3000 \
-e RCS_API_KEYS=sk-rcs-your-secret-key-here \
-e RCS_BASE_URL=https://rcs.example.com \
-v rcs-data:/app/data \
--restart unless-stopped \
rcs:latest
```
### Docker Compose
```yaml
version: "3.8"
services:
rcs:
build:
context: .
dockerfile: packages/remote-control-server/Dockerfile
args:
VERSION: "0.1.0"
ports:
- "3000:3000"
environment:
- RCS_API_KEYS=sk-rcs-your-secret-key-here
- RCS_BASE_URL=https://rcs.example.com
volumes:
- rcs-data:/app/data
restart: unless-stopped
volumes:
rcs-data:
```
启动:
```bash
docker compose up -d
```
## 环境变量参考
### 服务器端
| 变量 | 必填 | 默认值 | 说明 |
|------|------|--------|------|
| `RCS_API_KEYS` | **是** | _(空)_ | API 密钥列表,逗号分隔。用于客户端认证和 JWT 签名。**务必设置强密钥** |
| `RCS_PORT` | 否 | `3000` | 服务监听端口 |
| `RCS_HOST` | 否 | `0.0.0.0` | 服务监听地址 |
| `RCS_BASE_URL` | 否 | `http://localhost:3000` | 外部访问 URL。用于生成 WebSocket 连接地址,必须与客户端实际访问的地址一致 |
| `RCS_VERSION` | 否 | `0.1.0` | 版本号,显示在 `/health` 响应中 |
| `RCS_POLL_TIMEOUT` | 否 | `8` | V1 工作轮询超时(秒) |
| `RCS_HEARTBEAT_INTERVAL` | 否 | `20` | 心跳间隔(秒) |
| `RCS_JWT_EXPIRES_IN` | 否 | `3600` | JWT 令牌有效期(秒) |
| `RCS_DISCONNECT_TIMEOUT` | 否 | `300` | 断线判定超时(秒) |
| `RCS_WS_IDLE_TIMEOUT` | 否 | `30` | WebSocket 空闲超时Bun 发送协议级 ping |
| `RCS_WS_KEEPALIVE_INTERVAL` | 否 | `20` | 服务端→客户端 keep_alive 帧间隔(秒),防止反向代理关闭空闲连接 |
### 客户端Claude Code CLI
| 变量 | 必填 | 说明 |
|------|------|------|
| `CLAUDE_BRIDGE_BASE_URL` | **是** | RCS 服务器地址,例如 `https://rcs.example.com`。设置此变量即启用自托管模式,跳过 GrowthBook 门控 |
| `CLAUDE_BRIDGE_OAUTH_TOKEN` | **是** | 认证令牌,必须与服务器端 `RCS_API_KEYS` 中的某个值匹配 |
| `CLAUDE_BRIDGE_SESSION_INGRESS_URL` | 否 | WebSocket 入口地址(默认与 `CLAUDE_BRIDGE_BASE_URL` 相同) |
| `CLAUDE_CODE_REMOTE` | 否 | 设为 `1` 时标记为远程执行模式 |
## Claude Code 客户端连接
### 1. 设置环境变量
在运行 Claude Code 的机器上设置:
```bash
export CLAUDE_BRIDGE_BASE_URL="https://rcs.example.com"
export CLAUDE_BRIDGE_OAUTH_TOKEN="sk-rcs-your-secret-key-here"
```
### 2. 启动 Claude Code
```bash
# 使用 dev 模式BRIDGE_MODE 默认启用)
bun run dev
# 或使用构建产物
bun run dist/cli.js
```
### 3. 执行 /remote-control 命令
在 Claude Code 的 REPL 中输入:
```
/remote-control
```
环境型 Remote Control例如 `claude remote-control` 子命令)会向 RCS 注册环境,注册成功后在终端显示连接 URL
```
https://rcs.example.com/code?bridge=<environmentId>
```
交互式 REPL 方式(`--remote-control``/remote-control`)在某些桥接模式下也可能直接给出会话 URL
```
https://rcs.example.com/code/session_<id>
```
两种 URL 都可以直接在浏览器打开并远程操控当前会话;只有 environment 模式才会出现在 Web UI 的环境列表中。
若已连接,再次执行 `/remote-control` 会显示对话框,包含以下选项:
- **Disconnect this session** — 断开远程连接
- **Show QR code** — 显示/隐藏二维码
- **Continue** — 保持连接,继续使用
也可通过 CLI 参数直接启动:
```bash
claude remote-control
# 或简写
claude rc
# 或
claude bridge
```
## Web UI 控制面板
通过 `/remote-control` 命令获取 URL 后,在浏览器打开即可使用。
### 技术栈v22026-04-18 重构)
Web UI 已从原生 JS 重构为 **React + Vite + Radix UI**
- **框架**: React 19 + Vite 构建TypeScript
- **UI 组件**: Radix UI primitivesDialog、Tabs、Select、Popover 等)
- **聊天组件**: 完整的 ACP 聊天界面,支持 Plan 可视化、工具调用展示、权限审批
- **AI Elements**: 独立的 AI 交互组件库message、reasoning、tool、code-block、prompt-input 等)
- **ACP 直连**: 支持 QR 码扫描自动跳转 ACP 直连视图(`ACPDirectView`
- **主题系统**: 暗色/亮色主题切换,遵循 Impeccable 设计系统
### 功能
- 查看已注册的运行环境environment 模式),区分 ACP Agent 和 Claude Code 类型
- 创建和管理会话
- 实时查看对话消息和工具调用
- 查看 Autopilot 状态(`standby` / `sleeping`)和自动运行指示
- 查看 authoritative task snapshots 驱动的 Tasks 面板
- 审批 Claude Code 的工具权限请求
- 权限模式选择器6 种模式:默认/自动接受编辑/跳过权限/规划/不询问/自动判断)
- 模型选择器(可选可用模型)
- Plan 可视化(进度条、状态图标、优先级标签)
- ACP QR 扫描自动跳转到 ACP 聊天界面
Web UI 使用 UUID 认证(无需用户账户),适合受信任网络环境。
## ACP 支持
RCS 支持 ACP (Agent Client Protocol) agent 通过 `acp-link` 包接入。
### 架构
```
acp-link ──REST注册──► RCS POST /v1/environments/bridge
acp-link ──WS identify──► RCS WebSocket (携带 agentId)
acp-link ◄──ACP relay──► RCS ◄──Web UI WS──► 浏览器
```
### 后端组件
| 文件 | 职责 |
|------|------|
| `src/routes/acp/index.ts` | ACP REST 路由agents 列表、channel groups、relay |
| `src/transport/acp-ws-handler.ts` | ACP WebSocket 处理agent 注册、心跳、消息转发 |
| `src/transport/acp-relay-handler.ts` | 前端 WS → acp-link 透传 + EventBus inbound 转发 |
| `src/transport/acp-sse-writer.ts` | SSE event stream 供外部消费者订阅 |
### acp-link 连接
详见 [acp-link 文档](./acp-link.md)。
```bash
# 在 RCS 环境中启动 acp-link
# 注意claude 本身不支持 ACP需要用 ccb-bun --acp
ACP_RCS_URL=http://localhost:3000 \
ACP_RCS_TOKEN=sk-rcs-your-key \
acp-link ccb-bun -- --acp
```
ACP session 在 Web UI 中显示品牌色标签,与普通 Claude Code session 区分。
## 工作流程详解
```
┌──────────────────────────────────────────────────────────┐
│ 完整工作流程 │
└──────────────────────────────────────────────────────────┘
1. Claude Code CLI 启动,设置环境变量指向自托管 RCS
2. 用户执行 /remote-control 命令
3. 注册环境
CLI ──POST /v1/environments/bridge──► RCS
CLI ◄── { environment_id, environment_secret } ── RCS
4. 终端显示连接 URL
https://rcs.example.com/code?bridge=<environmentId>
5. 开始工作轮询(循环)
CLI ──GET /v1/environments/:id/work/poll──► RCS
(长轮询,等待任务分配,超时 8 秒后重试)
6. 浏览器打开 URL → Web UI 创建任务
Browser ──POST /web/sessions──► RCS
RCS 分配 work 给正在轮询的 CLI
7. CLI 收到任务并确认
CLI ◄── { id, data: { type, sessionId } } ── RCS
CLI ──POST /v1/environments/:id/work/:workId/ack──► RCS
8. 建立会话连接
CLI ──WebSocket /v1/session_ingress──► RCS
(或使用 V2 的 SSE + HTTP POST
9. 双向通信
CLI ──消息/工具调用结果──► RCS ──► Browser
CLI ◄──权限审批/指令───── RCS ◄──── Browser
CLI ──automation_state / task_state──► RCS ──► Browser
10. 心跳保活(每 20 秒)
CLI ──POST /v1/environments/:id/work/:workId/heartbeat──► RCS
11. 任务完成 → 归档会话 → 注销环境
```
## 故障排查
### Web UI 看不到当前 Autopilot 状态
- `standby`proactive 已开启,正在等待下一个 tick
- `sleeping`:模型正在 `SleepTool` 等待窗口中
这两个状态通过 worker `external_metadata.automation_state` 上报。如果页面只显示普通 working spinner优先检查 CLI 和 RCS 之间的 worker metadata PUT 是否成功。
### CLI 无法连接
```
Error: Remote Control is not available in this build.
```
**原因**`BRIDGE_MODE` feature flag 未启用。
**解决**:使用 dev 模式(默认启用)或确保构建时包含 `BRIDGE_MODE` flag。
### 认证失败 (401)
```
Error: Unauthorized
```
**检查项**
1. `CLAUDE_BRIDGE_OAUTH_TOKEN` 是否与 `RCS_API_KEYS` 中的值匹配
2. API Key 是否包含多余的空格或换行
3. 两个环境变量是否都已正确设置
### WebSocket 连接中断
**检查项**
1. 如果使用反向代理,确认已正确配置 WebSocket 升级(`Upgrade` / `Connection` 头)
2. 代理的 `proxy_read_timeout` 是否足够大(建议 86400 秒)
3. 网络防火墙是否允许 WebSocket 流量
### 健康检查
```bash
curl https://rcs.example.com/health
# 预期: {"status":"ok","version":"0.1.0"}
```
## 限制与注意事项
| 项目 | 说明 |
|------|------|
| 存储 | 纯内存存储Map服务器重启后所有会话和环境数据丢失 |
| 扩展 | 不支持水平扩展(无共享状态),单实例部署 |
| 并发 | 适合中小规模使用,大量并发会话可能需要性能调优 |
| 数据持久化 | `/app/data` 卷已预留但当前未使用,未来可能用于持久化 |
| Web UI 认证 | 基于 UUID无用户账户系统适合受信任网络环境 |
## 与云端模式对比
| 特性 | 云端 (Anthropic CCR) | 自托管 (RCS) |
|------|---------------------|--------------|
| 认证方式 | claude.ai OAuth 订阅 | API Key |
| GrowthBook 门控 | 需要 `tengu_ccr_bridge` 通过 | 自动跳过 |
| 功能标志 | 需要 `BRIDGE_MODE=1` | 同样需要 |
| 部署位置 | Anthropic 云端 | 用户自有服务器 |
| 数据流经 | Anthropic 基础设施 | 用户私有网络 |
| 依赖 | claude.ai 订阅 + OAuth | 仅需 API Key |
自托管模式的核心优势是:设置 `CLAUDE_BRIDGE_BASE_URL` 后,代码自动调用 `isSelfHostedBridge()` 返回 `true`,跳过所有 GrowthBook 和订阅检查,无需 claude.ai 账户即可使用。